【C++】什么情况下编辑器自动生成默认的构造函数?(详解)

  首先我们需要明确,在没有显示定义构造函数的时候,编辑器不一定会自动生成默认的构造函数

  对c++初学者来说存在一个误区,如果类没有定义任何构造函数,编译器会自动生成默认的构造函数。

正确的说法:

只有默认构造函数”被需要“的时候编译器才会生成默认构造函数。

那么什么时候是编辑器自己想生成的呢?这里我们给出了四个场景 :

场景一:含有类对象数据成员,该类对象类型有默认构造函数

class A
{
    
    
public:
	A()
	{
    
    
		cout << "A()" << endl;
	}
};
class B
{
    
    
public:
	A a;   //含有A类的成员
	int num;
};
void Test()
{
    
    
	B b;	//需要调用A类的默认构造函数
			//此时并没有给出显示定义的构造函数,但是编辑器会自动生成一个默认(无参)的构造函数
	cout << b.num << endl;
}

int main()
{
    
    
	Test();
	return 0;
}

原因: 编辑器在给B类生成无参的默认构造函数的初始化列表的位置调用A类的构造函数,完成对a对象的初始化。(num直接给成随机值了)

场景二: 基类带有默认构造函数的派生类

当一个类派生自一个含有默认构造函数的基类时,该类也符合编译器需要合成默认构造函数的条件。编译器合成的默认构造函数将根据基类声明顺序调用上层的基类默认构造函数。

class Base
{
    
    
public:
	Base()
	{
    
    
		cout << "Base()" << endl;
	}
};

class Derived :public Base
{
    
    
public:
	int d;
};

void Test()
{
    
    
	Derived d;
}

int main()
{
    
    
	Test();
	return 0;
}

原因:因为派生类被合成时需要显式调用基类的默认构造函数。

情景三:带有虚函数的类

类带有虚函数可以分为两种情况:

(1)类本身定义了自己的虚函数
(2) 类从继承体系中继承了虚函数(成员函数一旦被声明为虚函数,继承不会改变虚函数的”虚性质“)。

   这两种情况都使一个类成为带有虚函数的类。这样的类也满足编译器需要合成默认构造函数的类,原因是含有虚函数的类对象都含有一个虚表指针vptr,编译器需要对vptr设置初值以满足虚函数机制的正确运行,编译器会把这个设置初值的操作放在默认构造函数中。
  如果设计者没有定义任何一个默认构造函数,则编译器会合成一个默认构造函数完成上述操作,否则,编译器将在每一个构造函数中插入代码来完成相同的事情。

情景四:虚拟继承下

  虚继承也会在子类对象中被合成一个指向虚基类的指针,因此也要被初始化,所以必须要构造函数,虚基类或者虚继承保证子类对象中只有一份虚基类的对象。

总结一下:
  不符合以上4种情形的而且没有声明任何构造函数的,编译器并不会合成默认的构造函数;
  并且合成的默认构造函数并不会初始化类的内置类型复合类型的数据成员。

扫描二维码关注公众号,回复: 13137135 查看本文章

猜你喜欢

转载自blog.csdn.net/Vcrossover/article/details/113107520
今日推荐