构造函数初始化问题

xiaolomg 2012-10-25 11:09:20
看代码:
class ClassA
{
public:
ClassA(int aData):m_Data(aData),mC(aData),mB(mC,*this)
private:
ClassC mC;
ClassB mB;
int m_Data;
};

类A比较复杂,在构造函数初始化列表中,初始化了自己的成员变量m_Data,mc,还要以自己的本身初始化mB;
编译器会warning,如何改变代码才能没有warning呢?(PS:不要试图去修改ClassB,如果木有必要的话)。
...全文
169 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
virtualxmars 2012-10-27
  • 打赏
  • 举报
回复
《C++语言的设计和演化》(中文版)P84页指出:
“理想情况是,如果交换两个声明的顺序会导致另一种不同的意思,那么这就应该是一个错误。“
virtualxmars 2012-10-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
改变下声明顺序不更简单。。
[/Quote]

6楼有回复

额,上面的第二种方案,mC,mB应该是值对象,而不是指针,没注意,不好意思。
还有就是,第二种方案要得到支持,ClassB和ClassC必须支持默认构造函数
b13438954778 2012-10-26
  • 打赏
  • 举报
回复
ClassA(int aData):m_Data(aData),mC(aData),mB(mC,*this)
好像写错了吧,能怎么写么?
zhousitiaoda 2012-10-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
亲,这个代码不能这么写,这样写会直接导致数据初始化异常。
初始化列表中的执行顺序不是程序员可以改变的,它们的执行顺序是由你在类中定义的成员顺序决定的。
这意味着即使你的意图是先初始化 m_Data,但它却是最后执行的。那么 mB的构造使用了mC和*this,而this所指向的对象中,m_Data的值还是木有意义的。最终~你得不到自己想要的东西

更合理的方法有简单的,还有复杂的:
简单的……
[/Quote]
改变下声明顺序不更简单。。
virtualxmars 2012-10-25
  • 打赏
  • 举报
回复
之所以建议你使用后面的方案,而不是草率地调整成员变量顺序,是因为让程序行为依赖于这些因素会导致很多莫名其妙,难以维护的bug。所以,还是明确地将初始化按顺序执行比较好。

我记得在《Effective C++》、或者是《More Effective C++》中,提到过这个问题。
virtualxmars 2012-10-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

成员初始化列表在类的构造函数执行前执行,因此 你这里 mB(mC, *this) 这个指向 this 的指针是一个野指针

你可以在 ClassA 构造函数内部来 初始化 ClassB
[/Quote]

该指针不野,对象定义,无论是在堆还是栈上,都会先分配内存,然后才调用构造函数的,而且会将分配到的内存首地址交给构造函数,作为this指针传入,所以不野。问题并不出在this指针上
virtualxmars 2012-10-25
  • 打赏
  • 举报
回复
亲,这个代码不能这么写,这样写会直接导致数据初始化异常。
初始化列表中的执行顺序不是程序员可以改变的,它们的执行顺序是由你在类中定义的成员顺序决定的。
这意味着即使你的意图是先初始化 m_Data,但它却是最后执行的。那么 mB的构造使用了mC和*this,而this所指向的对象中,m_Data的值还是木有意义的。最终~你得不到自己想要的东西

更合理的方法有简单的,还有复杂的:
简单的就是,用堆定义的对象替代:

class classA {
public:
ClassA(int aData) {
m_Data = aData;
mC = new ClassC(aData);
mB = new classB(aData,*this);
}

~ClassA() {
delete mB;
delete mC;
}

private:
ClassC *mC;
ClassB *mB;
int m_Data;
}


复杂的替代方案就涉及稍微晦涩一点的语法知识了:placement new,作用就是在指定内存位置调用构造函数,以构建对象:

class classA {
public:
classA(int aData) {
m_Data = aData;
new (&mC) ClassC(aData);
new (&mB) ClassB(aData, *this);
}

private:
ClassC *mC;
ClassB *B;
int m_Data;
}
若风09 2012-10-25
  • 打赏
  • 举报
回复
ClassA(int aData):m_Data(aData),mC(aData),mB(mC,*this)
这句话表示看不太懂
ouuyang 2012-10-25
  • 打赏
  • 举报
回复
成员初始化列表在类的构造函数执行前执行,因此 你这里 mB(mC, *this) 这个指向 this 的指针是一个野指针

你可以在 ClassA 构造函数内部来 初始化 ClassB
npuhuxl 2012-10-25
  • 打赏
  • 举报
回复
,mB(mC,*this)
初始化列表中可以使用this指针?

64,647

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧