码的一个C++有关虚拟继承的一个小程序,不知道为什么出错了,求解答TAT

时间:2023-02-24 00:08:52
#include<iostream>
using namespace std;
class A{
int a;
public:
A(int k=0){
a=k;
cout<<"Constructing A="<<a<<endl;};

};
class B{
public:
B(){cout<<"Constructing B"<<endl;};
};
class B1:virtual public B,virtual public A{
public:
B1(int i):A(i){cout<<"Constructing B1"<<endl;};
};
运行结果的第二行不应该是Constructing A=1 吗,为什么是默认参数0呢??
class B2:public A,virtual public B{
public:
B2(int j):A(j){cout<<"Constucting B2"<<endl;};
};
class D:public B1,public B2{
public:
D(int m,int n):B1(m),B2(n){
cout<<"Constructing D"<<endl;
};
};
int main()
{
D d(1,2);
}

6 个解决方案

#1


码的一个C++有关虚拟继承的一个小程序,不知道为什么出错了,求解答TAT
运行结果的第二行不应该是Constructing A=1吗,为什么是默认参数0呢????

#2


应该是这样:
虚基类的构造 是在最外层类D构造函数构造的 ,中间的类构造不会构造虚基类。
相当于这样:
D(int m,int n):B(), A(0),B1(m),B2(n){
cout<<"Constructing D"<<endl;
};

#3


继承链上的基类对其虚基类的构造调用会被忽略,如果不在最外层派生类上显示调用虚基类的构造,则默认调用虚基类的无参构造函数,此时如果虚基类没有无参构造函数,编译报错。

#4


单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

#5


3楼已经正确解释了

如果改成: A(int k)  (没有默认参数) 那么编译报错

#6


虚基类要由最终派生类初始化。。。。

#1


码的一个C++有关虚拟继承的一个小程序,不知道为什么出错了,求解答TAT
运行结果的第二行不应该是Constructing A=1吗,为什么是默认参数0呢????

#2


应该是这样:
虚基类的构造 是在最外层类D构造函数构造的 ,中间的类构造不会构造虚基类。
相当于这样:
D(int m,int n):B(), A(0),B1(m),B2(n){
cout<<"Constructing D"<<endl;
};

#3


继承链上的基类对其虚基类的构造调用会被忽略,如果不在最外层派生类上显示调用虚基类的构造,则默认调用虚基类的无参构造函数,此时如果虚基类没有无参构造函数,编译报错。

#4


单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

#5


3楼已经正确解释了

如果改成: A(int k)  (没有默认参数) 那么编译报错

#6


虚基类要由最终派生类初始化。。。。