如何防止使用尚未构造的班级成员? [英] how to prevent usage of class members not yet constructed?
问题描述
我有以下课程:
A类{上市:A(){x = 0;std :: cout<<默认的ctor()\ n;}A(int x_){x = x_;std :: cout<<普通的ctor()\ n";}int x;};B级{上市:B(){std :: cout<<"B ctor()\ n";}私人的:std :: string str;};
和一个以对象A为参数创建对象B的函数:
BcreateB(const A& a){std :: cout<<; int:"<< a.x<<"\ n";返回B();}
如果我设计一个类C,它具有类型A和B的成员,并且在构造A对象之前先构造B对象,但要使用A对象这样做,它将在不创建A的情况下进行编译.警告,但它会悄无声息地输入错误:
C类{上市:C():b(createB(a)),a(10){}私人的:B b;A a;};int main(){C c;返回0;}
当然,上面的示例是一个简单的示例,但是我已经在现实世界中以更复杂的代码看到了它(现在是星期五,晚上8:30,我刚刚修复了导致段错误的错误)./p>
如何防止这种情况发生?
我同意其他人的建议,即设计者有责任确保在使用对象之前将其初始化.对于您的情况,我看到了两种解决方法:
首先(也是最简单的),在类定义中颠倒 a
和 b
的顺序:
C类{上市:C():b(createB(a)),a(10){}私人的:A a;B b;};
第二,如果您想真的强调它的初始化发生在其他成员的初始化之前,则可以将 a
移至基类:
CBase类{受保护的:CBase():a(10){}受保护的:A a;};C类:私有CBase{上市:C():b(createB(a)){}私人的:B b;};
I have the following classes:
class A
{
public:
A() { x = 0; std::cout<<"A default ctor()\n"; }
A(int x_) { x = x_; std::cout<<"A normal ctor()\n"; }
int x;
};
class B
{
public:
B() { std::cout<<"B ctor()\n"; }
private:
std::string str;
};
and a function which creates an object B, taking an object A as parameter:
B
createB(const A& a) {
std::cout<<"a int: "<<a.x<<"\n";
return B();
}
if I design a class C, which has members of type A and B and constructs the B-object before A-object is constructed but using the A object to do so, this will compile without warnings but it will silently enter a bug:
class C
{
public:
C(): b(createB(a)), a(10) {}
private:
B b;
A a;
};
int main()
{
C c;
return 0;
}
Of course, the above example is a trivial one, but I've seen it in real world, in much more complex code (it's Friday, 8:30 PM and I just fixed this bug which led to segfaults).
How can I prevent this from happening?
I would agree with what others have suggested, namely that the onus is on the designer to ensure that objects are initialized before use. I see two ways of doing that in your case:
First (and easiest), reverse the order of a
and b
in the class definition:
class C
{
public:
C(): b(createB(a)), a(10) {}
private:
A a;
B b;
};
Second, you could move a
to a base class if you want to really emphasize that it's initialization occurs before that of other members:
class CBase
{
protected:
CBase(): a(10) {}
protected:
A a;
};
class C : private CBase
{
public:
C(): b(createB(a)) {}
private:
B b;
};
这篇关于如何防止使用尚未构造的班级成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!