【C/C++】C++11 类的 默认构造函数 “= default” 用法
到底要不要使用 = default 声明默认构造函数?
两种情况对比
情况1:使用类内初始化,不写默认构造函数
class Rectangle {
private:double width {1.0};double height {1.0};std::string name {"Rectangle"};public:// 没有声明默认构造函数// 编译器会自动生成一个Rectangle(double w, double h, const std::string& n) : width(w), height(h), name(n) {}void print() {std::cout << name << ": " << width << " x " << height << std::endl;}
};
情况2:使用类内初始化,显式写 = default
class Rectangle {
private:double width {1.0};double height {1.0};std::string name {"Rectangle"};public:Rectangle() = default; // 显式要求编译器生成默认构造函数Rectangle(double w, double h, const std::string& n) : width(w), height(h), name(n) {}void print() {std::cout << name << ": " << width << " x " << height << std::endl;}
};
关键区别
当不写默认构造函数时:
- 编译器会自动生成一个默认构造函数
- 这个自动生成的构造函数会使用类内初始值来初始化成员变量
- 可以正常创建对象:
Rectangle rect;
当显式写 = default 时:
- 效果与编译器自动生成的完全相同
- 只是更明确地表达了设计意图
实际测试
#include <iostream>
#include <string>class RectangleA {
private:double width {1.0};double height {1.0};std::string name {"Rectangle"};
public:// 没有默认构造函数声明void print() {std::cout << name << ": " << width << " x " << height << std::endl;}
};class RectangleB {
private:double width {1.0};double height {1.0};std::string name {"Rectangle"};
public:RectangleB() = default; // 显式默认void print() {std::cout << name << ": " << width << " x " << height << std::endl;}
};int main() {RectangleA rect1; // 正常工作!使用类内初始值RectangleB rect2; // 正常工作!使用类内初始值rect1.print(); // 输出: Rectangle: 1 x 1rect2.print(); // 输出: Rectangle: 1 x 1return 0;
}
什么时候需要显式写 = default?
在以下几种情况下需要:
1. 有其他构造函数时
class Rectangle {
private:double width {1.0};double height {1.0};
public:// 如果只有这个构造函数,默认构造函数不会被自动生成Rectangle(double w, double h) : width(w), height(h) {}// 需要显式要求编译器生成默认构造函数Rectangle() = default;
};
2. 需要明确的代码文档
class Rectangle {
private:double width {1.0};double height {1.0};
public:Rectangle() = default; // 明确表示:我需要默认构造函数// 其他代码...
};
3. 在头文件中显式定义,在源文件中实现特殊逻辑
// .h 文件
class Rectangle {
private:double width {1.0};double height {1.0};
public:Rectangle(); // 声明但不 = default
};// .cpp 文件
Rectangle::Rectangle() {// 可能有一些特殊的初始化逻辑std::cout << "Rectangle created with default values" << std::endl;
}
总结
- 不写默认构造函数:编译器自动生成,使用类内初始值 ✅
- 写
= default:效果相同,但更明确意图 ✅ - 只有在有其他构造函数时,才需要显式写
= default来保留默认构造函数
