如何防止使用尚未构造的班级成员? [英] how to prevent usage of class members not yet constructed?

查看:33
本文介绍了如何防止使用尚未构造的班级成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆