什么情况下C++编译器会生成默认的构造函数

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

注意:这种说法是错误的。

正确的说法:惟有默认构造函数”被需要“的时候编译器才会合成默认构造函数。

那什么情况下是“被需要”的时候?

以下有四种情况编译器会自动合成默认构造函数

情况1 含有类对象数据成员,该类对象类型有默认构造函数

即:一个class含有类对象数据成员,该类对象类型有默认构造函数sA包含了一个对象成员objectB,而这个对象成员定义了(classB的)默认构造函数,那么编译器会为classA合成一个默认构造函数

class A
{
public:
	A()
	{
		cout << "A()" << endl;
	}
};
class B
{
public:
	A a;
	int num;
};
void Test()
{
	B b;
	cout << b.num << endl;
}

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

 原因: 因为类成员对象有默认构造函数,那么编译器就需要 显式的来调用这个类成员对象的 构造函数。而编译器想显式的调用类成员对象的默认构造函数,就需要自己来合成一些代码来调用。但是记住,编译器合成的默认构造函数 仅仅调用类成员对象的默认构造函数,而不对我们类里面的其它变量做任何初始化操作

情形2 基类带有默认构造函数的派生类

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

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

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

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

void Test()
{
	Derived d;
}

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

情形3 带有虚函数的类

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

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

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

情形4 带有虚基类的类
     虚继承也会在子类对象中被合成一个指向虚基类的指针,因此也要被初始化,所以必须要构造函数,虚基类或者虚继承保证子类对象中只有一份虚基类的对象。
  
 总结一下: 不符合以上4种情形的而且没有声明任何构造函数的,编译器并不会合成默认的构造函数;
                   并且合成的默认构造函数并不会初始化类的内置类型复合类型的数据成员。



  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: C++类不存在默认构造函数是指在定义一个C++类时,如果没有显式地声明或定义默认构造函数,那么编译器就不为该类生成默认构造函数默认构造函数一个没有任何参数的构造函数,它负责在创建对象时,给对象的成员变量初始化。当我们没有定义任何构造函数时,编译器默认生成一个默认构造函数。但是,如果我们在类中显式定义了任何其他构造函数编译器就不生成默认构造函数了。 当一个没有默认构造函数时,我们在创建对象时必须显式地调用有参构造函数来进行对象的初始化。如果我们没有定义有参构造函数,那么编译器报错,因为它无法自动创建默认构造函数。 为什么C++类不存在默认构造函数呢?这是因为C++允许我们在定义类时通过构造函数对对象进行初始化,这样可以确保对象的合法性和一致性。但是,如果自动生成默认构造函数,那么对象就使用默认值进行初始化,可能导致对象的成员变量处于一个不合理的状态,进而引发错误。 为了避免这种错误,C++规定没有显式定义或声明默认构造函数的类,是无法使用默认构造函数的。因此,我们必须显式地定义或声明一个有参构造函数来对对象进行初始化。这样可以保证对象始终处于一个合理的状态,提高程序的稳定性和安全性。 ### 回答2: C++类如果没有显式声明构造函数编译器为其生成一个默认构造函数。然而,如果类中有一些特殊的成员、基类或者虚函数,编译器就无法生成默认构造函数。 当类中存在有以下情况时,编译器无法生成默认构造函数: 1. 类的成员或基类没有默认构造函数:如果类的成员或者基类没有默认构造函数编译器无法通过自动生成默认构造函数来初始化这些成员或者基类,因此无法生成默认构造函数。 2. 类定义了带参数的构造函数:如果类中定义了任何构造函数(不论是默认参数构造函数还是重载的构造函数),编译器认为你提供的构造函数相对于默认构造函数更为重要,所以不再为类生成默认构造函数。 3. 类定义了虚函数:当类中定义了虚函数时,编译器无法自动生成默认构造函数,因为默认构造函数无法初始化虚函数的相关信息(例如虚函数表)。 为了解决类没有默认构造函数的问题,可以手动为类编写一个构造函数来完成初始化工作,或者使用初始化列表来初始化类的成员或基类。总之,在需要使用默认构造函数的地方,我们需要手动为类提供一个默认构造函数,而不是依赖于编译器默认构造函数。 ### 回答3: C++中,类不存在默认构造函数的意思是,在定义一个类时,如果没有显式地定义构造函数,那么编译器自动生成默认构造函数构造函数是用来初始化对象的特殊成员函数,它在对象创建时自动调用。当我们没有为类定义任何构造函数时,编译器自动生成一个默认构造函数。 然而,当我们显式地定义了一个或多个构造函数时,编译器就不再自动生成默认构造函数了。这就是所谓的“类不存在默认构造函数”。 如果我们需要创建一个没有默认构造函数的类的对象,我们就必须显式地定义自己的构造函数,以确保对象可以被正确地初始化。否则,在实例化该类对象时将产生编译错误。 值得注意的是,当定义了至少一个自定义构造函数后,如果我们还想要使用默认构造函数,则需要手动显式地定义一个默认构造函数。 例如,下面是一个没有默认构造函数的类例: ```cpp class MyClass { public: MyClass(int value) { // 构造函数的实现 } }; ``` 在这个例中,我们定义了一个名为MyClass的类,它只有一个带有一个整型参数的构造函数。因此,如果我们在没有提供参数的情况下实例化MyClass的对象,将出现编译错误。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值