大家帮我看看这个C++程序啊!

#include"iostream.h"classbase{protected:intprivatel;public:base(intp){privatel=p;}};c... #include "iostream.h"
class base
{
protected:
int privatel;
public:
base(int p){privatel=p;}
};
class derived1:virtual public base
{
public:
derived1(int p1):base(p1){};
int get_privater(){return privatel;}
};
class derived2:virtual public base
{
public:
derived2(int p2):base(p2){};
int get_privater(){return privatel;}
};
class derived12:public derived1,public derived2
{
public:
derived12(int p1,int p2,int pb):derived1(p1),derived2(p2),base(pb){};
};
void main()
{
derived12 d(10,20,30);
cout<<"privatel from derived1:"<<d.derived1::get_privater();
cout<<"\nprivatel from derived2:"<<d.derived2::get_privater();
cout<<"\n";
}
为什么输出是30,30?我觉得应该是10,20啊,derived1和derived2分别对应的是10和20阿
你讲的关于虚继承的我都懂了,可是在调用构造函数derived12::derived12(int,int,int)时总是按照先derived1再derived2再base的顺序吗?跟初始化参数表无关吗?书上说是按照派生类定义时的顺序,啥是派生类定义时的顺序阿,糊涂了......
展开
 我来答
百度网友60d7eecf4
2007-03-25 · TA获得超过198个赞
知道答主
回答量:170
采纳率:0%
帮助的人:0
展开全部
虚继承中每个子类只有一份它们的虚基类的拷贝,所以不管是在derived1、derived2还是derived12中,他们的的数据成员private1都只有唯一的一个,而没有另外的拷贝。你可以返回private1的引用来看出:

derived1::int& get_privater(){return privatel;}
derived2::int& get_privater(){return privatel;}

cout<< "privatel from derived1: "<< &d.derived1::get_privater();
cout<< "\nprivatel from derived2: "<< &d.derived2::get_privater();

你会发现它们的地址是相同的,既对于虚基类中的private1它们没有另外的拷贝,各个类人手一份。

所以在这句中:

derived12(int p1,int p2,int pb)
:derived1(p1), derived2(p2), base(pb)
{
};

虚基类在最后构造,derived1(p1), derived2(p2), base(pb)都是对derived12中的同一个数据成员private1初始化,所以derived2用p2来初始化private1时把derived1用p1初始化的值给覆盖掉了,同样base(pb)也把p2初始化的private1覆盖掉。所以最后其值为30。如果你这样:

derived12(int p1,int p2,int pb)
:base(p1), derived1(pb), derived2(p2)
{
};

那么你测试的结果就都是p1的值。

我故意不按顺序写就意在告诉你对于使用虚继承的基类来说是个例外,因为一般的继承基类的部分都是在子类部分构造之前构造,但虚基类如果有数据成员那么它在各个子类中都必须在子类构造的时候构造,而且其构造是在子类的部分构造之后。

至于构造顺序,那是在单独的一个类中而论,其数据成员的初始化顺序需和声明时的一致。这一句中

derived12(int p1,int p2,int pb)
:base(p1), derived1(pb), derived2(p2)
{
};

如果base,derived1和derived2中有多个数据成员那么它们就需在其各自的构造函数中按各自的声明顺序来构造。在构造一般继承关系的子类中,对于基类的构造要放在初始化列表中子类数据成员的初始化之前。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式