首页 > 试题广场 >

下面程序输出结果是什么?

[单选题]
下面程序输出结果是什么?
#include<iostream>
using namespace std;
class A{
public:
	A(char *s)
	{
		cout<<s<<endl;
	}
	~A(){}
};
class B:virtual public A
{
public:
	B(char *s1,char*s2):A(s1){
		cout<<s2<<endl;
	}
};
class C:virtual public A
{
public:
	C(char *s1,char*s2):A(s1){
		cout<<s2<<endl;
	}
};
class D:public B,public C
{
public:
	D(char *s1,char *s2,char *s3,char *s4):B(s1,s2),C(s1,s3),A(s1)
	{
		cout<<s4<<endl;
	}
};
int main() {
	D *p=new D("class A","class B","class C","class D");
	delete p;
	return 0;
}
  • class A class B class C class D
  • class D class B class C class A
  • class D class C class B class A
  • class A class C class B class D
看了前面解释,还是分不清为什么选A不选D,试了一下,当D  的继承方式为:class D:public C,public B 时,就会是:ACBD。似乎也是C++的基础内容,记不得了。
发表于 2018-05-24 16:02:00 回复(0)
和参数顺序没关系的,和继承顺序有关
        A
     /      \
   B       C
    \       /
       D
加了virtual后, 继承关系是这样的.
不加的话是这样的
     A             A
     |              |
    B             C
        \         /
            D
发表于 2016-08-08 16:39:59 回复(4)
这个就是c++对象生成时的构造顺序问题,先构造继承过来的父类,然后同级按顺序构造,算下来顺序就是abcd了
虚继承解决继承二义性问题
发表于 2015-11-16 18:20:55 回复(0)
运行发现必须在class B & class C 以及 class D 中实现对继承的类A的构造,即“ :A(s1) ”等语句,但D实例对象时,真正起构造A类作用的是最后在D类中对A的构造,若把虚继承(类B/C)中A的构造改为“ :A(s2) ”不会造成结果影响。也就是说,虚继承解决继承二义性,虚继承中对基类的构造是该类类型的实例对象初始化,但D类型的实例对象对A类初始化只与D有关,不会再执行一次B/C中的构造,即ABCD。
发表于 2015-11-24 15:31:34 回复(2)
1 创建派生类对象时,程序先调用基类构造函数,再调用派生类构造函数
2 派生类有多个基类时,按派生类声明中的基类列表顺序调用构造函数
派生类有的多个基类中有虚基类时,优先调用虚基类的构造函数。
4 派生类并不继承基类的构造函数,所以将基类的构造函数声明为虚函数是没有意义的。(虽然语法上是对的)。
5 派生类构造函数的参数列表中,应当包含所有基类构造函数需要的参数
6 派生类构造函数的参数列表后,应当指明基类的构造函数,否则使用基类的默认构造函数;该指明顺序与基类构造函数调用顺序无关(派生类    有多个基类时)。
7 在多重派生中,由同一个初始基类派生的多个类作为派生类的基类时,该初代基类的构造函数只调用一次。

看过这7 点,自然就会了。

发表于 2019-08-29 11:44:36 回复(1)
对于D继承了B,C
加上virtual之后,系统会自动加入一个虚拟基类的拷贝,首先调用虚拟基类的构造函数,之后就不会打印了,
如果不加virtual的话,应该会打印两次基类的构造函数
发表于 2017-08-08 16:29:31 回复(0)
classD:publicB,publicC//此处的继承顺序决定,基类构造函数调用
{
    public:
    D(char*s1,char*s2,char*s3,char*s4):B(s1,s2),C(s1,s3),A(s1)
    {
        cout<<s4<<endl;
    }
};

发表于 2017-07-04 15:28:15 回复(0)
    派生类构造函数执行的次序:
   调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左到右);
   调用内嵌成员对象的构造函数,调用顺序按照它们在类中声明的顺序;
   派生类的构造函数体中的内容。
发表于 2015-11-24 20:53:59 回复(0)
对比虚继承和一般继承中对基类的初始化
一般继承:派生类只需负责对其直接基类进行初始化,在由其直接基类负责对间接基类初始化。即D负责B和C的初始化,B和C负责对A的初始化。
虚继承:虚基类的初始化直接由派生类负责。即最后的派生类中不仅要负责对其直接基类的进行初始化,还要负责对虚基类初始化。
问题:D会初始化A,B和C也会初始化A,则A的构造函数会被调用3次吗?
回答:C++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其它派生类对虚基类的构造函数的调用。
发表于 2019-02-11 12:12:44 回复(0)
初始化链表初始化顺序和定义的顺序相同,这是一个常考点。
发表于 2017-06-30 14:29:11 回复(0)
先执行父类构造函数 在执行成员变量的构造函数 最后执行本类的构造函数。。。。。。
发表于 2017-11-15 19:14:54 回复(0)
虚继承解决二义
发表于 2017-02-23 07:54:26 回复(0)
       A
     /      \
   B       C
    \       /
       D
加了virtual后, 继承关系是这样的.
不加的话是这样的
     A             A
     |              |
    B             C
        \         /
            D
1 创建派生类对象时,程序先调用基类构造函数,再调用派生类构造函数
2 派生类有多个基类时,按派生类声明中的基类列表顺序调用构造函数
派生类有的多个基类中有虚基类时,优先调用虚基类的构造函数。
4 派生类并不继承基类的构造函数,所以将基类的构造函数声明为虚函数是没有意义的。(虽然语法上是对的)。
5 派生类构造函数的参数列表中,应当包含所有基类构造函数需要的参数
派生类构造函数的参数列表后,应当指明基类的构造函数,否则使用基类的默认构造函数;该指明顺序与基类构造函数调用顺序无关(派生类有多个基类时)。
7 在多重派生中,由同一个初始基类派生的多个类作为派生类的基类时,该初代基类的构造函数只调用一次。

发表于 2023-06-28 15:40:33 回复(0)
派生类构造函数执行的次序:
   调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左到右)
   调用内嵌成员对象的构造函数,调用顺序按照它们在类中声明的顺序;
   派生类的构造函数体中的内容。
发表于 2022-10-02 15:40:39 回复(0)
  • 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义

  • 利用虚继承可以解决菱形继承问题

发表于 2022-03-03 14:52:48 回复(0)
1、编译器必须在构造派生对象之前构造基类的对象组件 
2、通过B,C两条路径将s1传递给A存在冲突,在基类为虚时,禁止信息通过中间类自动传递给基类
发表于 2021-12-22 11:23:43 回复(0)
本人学的烂,整合一下回答。
虚类,无论派生出多少个子类(更应该说,是派生链子上有多深),它们都共用一个虚类作为备份。所以,如果是public B:public A;public C:public A;结果就是ABACD,而且这里默认构造函数还不用声明A的默认构造函数;但是这里公用一个A,结果是ABCD。
因为默认构造函数是带参数的,而带参的声明默认构造函数的同时必须声明父类的。如果没带参数,就默认编译器自己调用父类的默认构造函数。
发表于 2021-09-24 23:05:27 回复(0)
①虚继承,基类A仅调用1次
②调用基类的构造函数:按继承声明自左向右进行
发表于 2021-02-02 13:51:40 回复(0)
虚继承
发表于 2020-08-07 00:41:51 回复(0)

虚继承,只调用了一次A的构造函数

发表于 2020-03-03 18:20:04 回复(0)