在 C++ 中,默认构造函数 是一个没有参数的构造函数,或者所有参数都有默认值的构造函数。如果在类中 未声明任何构造函数,编译器会自动生成一个 public 默认构造函数。然而,如果声明了至少一个 其他构造函数(比如带参数的构造函数),编译器将 不再生成 自动提供的默认构造函数。如果在这样的类中需要默认构造函数,则需要显式声明(例如,通过 ClassName() = default;)。
class Foo { public: Foo(int x) {} // 用户自定义构造函数 // Foo() 默认构造函数将不再由编译器生成! }; Foo f; // 编译错误 — 没有默认构造函数!
要在这种情况下显式创建默认构造函数,应添加:
class Foo { public: Foo() = default; Foo(int x) {} };
"如果您只有一个带参数的构造函数,是否可以在没有参数的情况下创建该类的对象?为什么?"
回答: 不可以!因为如果声明了 任何构造函数,编译器将不再自动添加默认构造函数。要在没有参数的情况下创建对象,需要在声明中显式添加默认构造函数。
故事
在一个大型项目中,编写了一个用于序列化数据的类层次结构,其中所有“子”类只有特定的带参数构造函数。经过重构后发现,当使用 STL 容器(例如 std::vector)与这些类时,编译中止:容器需要默认构造函数,但不存在。这个问题只有在显式声明默认构造函数后才解决.
故事
在一个使用模板的项目中,一个适配器类只声明了带参数的构造函数以传递资源。同时,一个库要求有默认构造函数才能正常工作(通过模板类型创建临时对象)。出现了神秘的链接错误,开发者们长时间无法解释,直到实现了显式的默认构造函数.
故事
代码中存在从 C++98 迁移到 C++11 的情况,尝试使用 "= default" 显式声明默认构造函数。在旧编译器上会出现错误或忽略新的语法结构。这表明,并非所有开发者都理解显式实现的默认构造函数和编译器生成的默认构造函数以及新的 "= default" 语法之间的区别.