C中虚继承类构造函数的正确写法.docx
- 文档编号:7013129
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:6
- 大小:17.91KB
C中虚继承类构造函数的正确写法.docx
《C中虚继承类构造函数的正确写法.docx》由会员分享,可在线阅读,更多相关《C中虚继承类构造函数的正确写法.docx(6页珍藏版)》请在冰豆网上搜索。
C中虚继承类构造函数的正确写法
C++中虚继承类构造函数的正确写法
时间:
2015-08-2621:
57:
52 阅读:
15 评论:
0 收藏:
0 [点我收藏+]
标签:
class style log com http 代码 si src it
最近工作中某个软件功能出现了退化,追查下来发现是一个类的成员变量没有被正确的初始化。
这个问题与C++存在虚继承的情况下派生类构造函数的写法有关。
在此说明一下错误发生的原因,希望对更多的人有帮助。
我们代码中存在虚继承的类的继承结构与下图类似,并不是教科书中经典的菱形结构。
从Intermediate1和Intermediate3到Base2的继承都是虚继承。
Base1和Base2都包含一些成员变量,并提供了相应的构造函数接受指定的初始化值。
Base2还有一个缺省构造函数,把其成员变量都初始化为0。
Intermediate1,2,3也都提供了一个构造函数接受指定的初始化值,并在在初始化列表里调用Base1和Base2的构造函数完成初始化。
一位同事在做重构时,不小心把Final的代码改成了:
classFinal:
publicIntermediate2,publicIntermediate3{
public:
Final(inta,intb,intc)
:
Intermediate2(a,b,c),
Intermediate3(b,c)
{
}
};
classIntermediate1:
publicBase1,virtualpublicBase2{
public:
Intermediate1(inta,intb,intc)
:
Base1(a),
Base2(b,c)
{
}
};
classIntermediate2:
publicIntermediate1{
public:
Intermediate2(inta,intb,intc)
:
Intermediate1(a,b,c),
Base2(b,c)
{
}
};
classIntermediate3:
virtualpublicBase2{
public:
Intermediate3(intb,intc)
:
Base2(b,c)
{
}
};
看上去,Final的构造函数将调用Intermediate2和Intermediate3的构造函数分别将m_a,m_b和m_c初始化成指定的值。
可是,运行时发现m_b和m_c的值是0!
明显,这是调用了Base2的缺省构造函数。
原来,C++的规则是:
如果在继承链上存在虚继承的基类,则最底层的子类要负责完成该虚基类部分成员的构造。
我们可以显式调用虚基类的构造函数完成初始化。
如果不显式调用虚基类的构造函数,则编译器会调用虚基类的缺省构造函数。
如果不显式调用虚基类的构造函数,而虚基类没有定义缺省构造函数,则会出现编译错误。
很多时候,对于继承链上的中间类,我们也会在其构造函数中显式调用虚基类的构造函数,因为一旦有人要创建这些中间类的对象,我们也要保证它们得到正确的初始化。
所以,如果我们要把m_b和m_c初始化成指定的值,Final的构造函数的正确写法应该是这样:
Final(inta,intb,intc)
:
Base2(b,c),
Intermediate2(a,b,c),
Intermediate3(b,c)
{
}
完整的测试程序如下所示,有兴趣的同学可以自行编译运行一下。
也可以在调试器中单步运行Final的构造函数,看看前后两种写法分别是调用了Base2的哪个构造函数。
#include"stdafx.h"
#include
usingnamespacestd;
classBase1{
public:
Base1(inta):
m_a(a){}
protected:
intm_a;
};
classBase2{
public:
Base2(intb,intc):
m_b(b),m_c(c){}
Base2():
m_b(0),m_c(0){}
protected:
intm_b;
intm_c;
};
classIntermediate1:
publicBase1,virtualpublicBase2{
public:
Intermediate1(inta,intb,intc)
:
Base1(a),
Base2(b,c)
{
}
};
classIntermediate2:
publicIntermediate1{
public:
Intermediate2(inta,intb,intc)
:
Intermediate1(a,b,c),
Base2(b,c)
{
}
};
classIntermediate3:
virtualpublicBase2{
public:
Intermediate3(intb,intc)
:
Base2(b,c)
{
}
};
classFinal:
publicIntermediate2,publicIntermediate3{
public:
Final(inta,intb,intc)
:
Base2(b,c),
Intermediate2(a,b,c),
Intermediate3(b,c)
{
}
voidPrint(){
cout< } }; int_tmain(intargc,_TCHAR*argv[]) { FinalfinalObj(1,2,3); finalObj.Print(); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 中虚继承类构造函数的正确写法 继承 构造 函数 正确 写法