自动生成默认构造函数的情况以及相关解释
在 C++ 中,当一个类没有任何用户定义的构造函数时,编译器会自动为这个类生成一个默认构造函数。以下是具体情况的解释以及示例:
1. 带有默认构造函数的类成员对象
如果一个类没有任何构造函数,但它含有一个成员对象,而该成员对象有默认构造函数,那么编译器会为这个类合成一个默认构造函数。然而,这个合成操作只有在构造函数真正被需要(即,确实有对象创建动作)时才会发生。同时,这个类的构造函数必须按照成员对象在类中的声明顺序调用每个成员对象的默认构造函数。
#include <iostream>
class Member {
public:
Member() {
std::cout << "Member default constructor called" << std::endl;
}
};
class MyClass {
public:
Member member; // MyClass 自动生成默认构造函数, 调用 Member 的默认构造函数
};
int main() {
MyClass obj; // 此处会自动生成并调用 MyClass 默认构造函数
return 0;
}
2. 带有默认构造函数的基类
如果一个没有任何构造函数的派生类继承自一个有默认构造函数的基类,那么该派生类会合成一个构造函数,该构造函数调用基类的默认构造函数。
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base default constructor called" << std::endl;
}
};
class Derived : public Base {
// 编译器为 Derived 合成一个默认构造函数,调用 Base 的默认构造函数
};
int main() {
Derived obj; // 此处会自动生成并调用 Derived 默认构造函数,同时调用 Base 默认构造函数
return 0;
}
3. 带有虚函数的类
如果一个类声明了至少一个虚函数,编译器会为这个类合成一个默认构造函数,即使没有其他构造函数。
#include <iostream>
class MyClass {
public:
virtual void myFunction() { } // 声明虚函数
};
int main() {
MyClass obj; // 此处会自动生成并调用 MyClass 默认构造函数
return 0;
}
4. 带有虚基类的类
如果一个类继承自一个或多个虚基类,编译器会自动为这个类生成一个默认构造函数。
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base default constructor called" << std::endl;
}
};
class Derived : public virtual Base {
// 编译器为 Derived 合成一个默认构造函数,调用 Base 的默认构造函数
};
int main() {
Derived obj; // 此处会自动生成并调用 Derived 默认构造函数,同时调用 Base 默认构造函数
return 0;
}
5. 合成的默认构造函数只初始化基类子对象和成员类对象
编译器合成的默认构造函数只会初始化基类子对象和成员类对象。所有其他的非静态数据成员都不会被初始化,它们将保留未定义的初始值。
#include <iostream>
class Member {
public:
Member() {
std::cout << "Member default constructor called" << std::endl;
}
};
class MyClass {
public:
int x;
Member member; // MyClass 自动生成默认构造函数, 调用 Member 的默认构造函数
void print() {
std::cout << "x = " << x << std::endl; // x 是未初始化的,值是未定义的
}
};
int main() {
MyClass obj; // 此处会自动生成并调用 MyClass 默认构造函数
obj.print(); // 打印未初始化的 x 的值
return 0;
}
总结
自动生成默认构造函数的情况如下:
- 带有默认构造函数的类成员对象:类没有构造函数,但成员对象有默认构造函数。
- 带有默认构造函数的基类:派生类没有构造函数,但基类有默认构造函数。
- 带有虚函数的类。
- 带有虚基类的类。
- 合成的默认构造函数仅初始化基类子对象和成员类对象:而未初始化的非静态数据成员具有未定义的值。
这些情况确保了类在实例化时能够正确初始化其成员和基类,即使用户未显式定义构造函数。
标签:对象,成员,默认,编译器,五种,C++,基类,构造函数 From: https://blog.csdn.net/m0_72877724/article/details/139548907