C++不是说虚基类构造函数只被调用一次吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++不是说虚基类构造函数只被调用一次吗?相关的知识,希望对你有一定的参考价值。

#include <iostream>
using namespace std;
class bus

protected:
int weight;
public:
void show()

cout<<"bus weigth is:"<<weight<<endl;

void set(int weight)

this->weight=weight;

bus()

weight=0;
cout<<"虚基类bus只被初始化一次"<<weight<<endl;

;

class minibus:virtual public bus

public:
void show()

cout<<"minibus weigth is:"<<weight<<endl;

;

class maxbus:virtual public bus

public:
void show()

cout<<"maxbus weigth is:"<<weight<<endl;

;

void main()

bus a;
minibus b;
maxbus c;
a.show();
b.show();
c.show();
a.set(50);
a.show();
b.show();
c.show();

这个程序输出可以看到是虚基类的构造函数被调用了3次,这是什么原因?是因为我在最远派生类中没有使用构造函数造成的吗?但书上说程序会自动调用自定义的默认构造函数来初始化的哦,这是为什么?请高手指教下~

不知道是书没说明白还是你没看明白, 总之你完全理解错了。

所谓只调用一次, 是说每个对象的构造当中只调用一次。 如果多个对象当然调用多次

对比一下虚继承和非虚继承的差别:
如果B (非虚,后面就不写了)继承A, C也继承A,D继承B和C,最终D里有两份A的内容,D的对象构造的时候A的构造函数也会被调用两次。
如果 B 虚继承A , C也虚继承A, D继承B和C, 最终D的对象里只有一份从A继承下来的东西,D的对象构造的时候A的构造函数也只调用一次
参考技术A 虚基类的构造函数只被调用一次是指多继承情况下,每个对象只调用一次虚基类构造函数 ,这样避免发生二义性

C++编程经验:为虚基类做虚析构函数的必要性

这个要提一下,如果记不住就记住:如果不做虚析构函数,会有内存泄漏

解释

定义一个基类的指针p,在delete p时,如果基类的析构函数是虚函数,这时只会看p所赋值的对象,如果p赋值的对象是派生类的对象,就会调用派生类的析构函数;如果p赋值的对象是基类的对象,就会调用基类的析构函数,这样就不会造成内存泄露。

如果基类的析构函数不是虚函数,在delete p时,调用析构函数时,只会看指针的数据类型,而不会去看赋值的对象,这样就会造成内存泄露。

多少学点设计模式就清楚了。

#include <iostream>
using namespace std;
 
class Base{
//此处省去,一切从简
};

//接下来是一个子类
class Inherit :public Base{
//此处省去,一切从简
};

//重点看调用
int main()
{
	Base *p =  new Inherit;	//这种方式的调用,这时候有没有虚析构就不一样了
	delete p;
	Base *q = new Base;
	delete q;
	return 0;
}

以上是关于C++不是说虚基类构造函数只被调用一次吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++ ——虚继承时的构造函数

C++虚基类初始化

C++创建派生类对象时,调用构造函数顺序

为啥执行时没有执行基类的构造函数?

关于类继承的构造与析构调用分析

虚基类初始化问题