BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #17879同步于 2008/12/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

虚基类程序报错....

tsunami
2008/12/21镜像同步5 回复
一个典型的虚基类程序,在visual6.0下运行出错,大牛给解释下哦~ #include<iostream> using namespace std; class base //基类 { private: int m_data; public: base(int m) { m_data=m; cout<<"base construction"<<endl; } ~base() { cout<<"base deconstruction"<<endl; } void setdata(int data) { m_data=data; } int getdata() { return m_data; } }; class Fderiver1:virtual public base { private: int m_value; public: Fderiver1(int value, int data):base(data) { m_value=value; cout<<"Fderiver1 construction"<<endl; } ~Fderiver1() { cout<<"Fderiver1 deconstruction"<<endl; } }; class Fderiver2:virtual public base { private: int m_number; public: Fderiver2(int number, int data):base(data) { m_number=number; cout<<"Fderiver2 construction"<<endl; } ~Fderiver2() { cout<<"Fderiver2 deconstruction"<<endl; } }; class Sderiver:public Fderiver1, public Fderiver2 { private: int m_attrib; public: Sderiver(int attrib, int data ,int value, int number):Fderiver1(value,data),Fderiver2(number,data) { m_attrib=attrib; cout<<"Sderiver construction"<<endl; } ~Sderiver() { cout<<"Sderiver deconstruction"<<endl; } }; void main() { Sderiver object(3,4,5,6); object.setdata(10); }
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
vcpp机器人#1 · 2008/12/21
类Sderiver的构造函数的初始化列表中,少了对虚基类base的构造函数的调用 应该改为: Sderiver(int attrib, int data ,int value, int number):Fderiver1(value,data),Fderiver2(number,data),base(data) { ... } 在调用Sderiver的构造函数时,实际上只有它自己的构造函数调用了虚基类base的构造函数,它的基类Fderiver1和Fderiver2的构造函数没有调用虚基类base的构造函数。
bupteinstein机器人#2 · 2008/12/21
还真是这样,C++教材上又写错了。
tsunami机器人#3 · 2008/12/22
两个小疑问: (1)如果去掉virtual就不用在类Sderiver的构造函数的初始化列表中,对虚基类base的构造函数的调用; (2)针对加了virtual后运行结果,楼上能解释下构造函数的调用顺序嘛? 我理解的是: Sderiver->Fderiver1->base; Sderiver->Fderiver2 【 在 vcpp 的大作中提到: 】 : 类Sderiver的构造函数的初始化列表中,少了对虚基类base的构造函数的调用 : 应该改为: : Sderiver(int attrib, int data ,int value, int number):Fderiver1(value,data),Fderiver2(number,data),base(data) : ...................
tsunami机器人#4 · 2008/12/22
在调用Sderiver的构造函数时,实际上只有它自己的构造函数调用了虚基类base的构造函数,它的基类Fderiver1和Fderiver2的构造函数没有调用虚基类base的构造函数。 ls的意思是base的构造函数是Sderiver调用的哦, 而不是Fderiver1调用的? 能详细解释下基类和派生类构造函数的调用顺序嘛?
vcpp机器人#5 · 2008/12/22
对于第一个问题: 去掉virtual后,就不存在虚基类了,就是普通的继承.使用虚基类的作用是消除二义性. 对于第二个问题: 构造函数的调用顺序是: 在一个成员初始化列表中出现对虚基类和非虚基类构造函数的调用,则虚基类的构造函数先于非虚基类的构造函数的执行。 下面是验证程序: #include<iostream> using namespace std; class base //基类 { private: int m_data; public: base(int m) { m_data=m; cout<<"base construction "<<m<<endl; //<-------- } ~base() { cout<<"base deconstruction"<<endl; } void setdata(int data) { m_data=data; } int getdata() { return m_data; } }; class Fderiver1:virtual public base { private: int m_value; public: Fderiver1(int value, int data):base(data) { m_value=value; cout<<"Fderiver1 construction"<<endl; } ~Fderiver1() { cout<<"Fderiver1 deconstruction"<<endl; } }; class Fderiver2:virtual public base { private: int m_number; public: Fderiver2(int number, int data):base(data) { m_number=number; cout<<"Fderiver2 construction"<<endl; } ~Fderiver2() { cout<<"Fderiver2 deconstruction"<<endl; } }; class Sderiver:public Fderiver1, public Fderiver2 { private: int m_attrib; public: Sderiver(int attrib, int data ,int value, int number):Fderiver1(value,value),Fderiver2(number,number),base(data) //<-------------------- { m_attrib=attrib; cout<<"Sderiver construction"<<endl; } ~Sderiver() { cout<<"Sderiver deconstruction"<<endl; } }; void main() { Sderiver object(3,4,5,6); object.setdata(10); //system("pause"); } //程序最后输出: //base construction 4 // ................... 说明是类Sderiver的构造函数的初始化列表中先调用了对虚基类base的构造函数. 【 在 tsunami 的大作中提到: 】 : 两个小疑问: : (1)如果去掉virtual就不用在类Sderiver的构造函数的初始化列表中,对虚基类base的构造函数的调用; : (2)针对加了virtual后运行结果,楼上能解释下构造函数的调用顺序嘛? : ...................