c++ - C++ 类是否具有默认构造函数以及在以下情况下调用哪些构造函数?

标签 c++ class object constructor default-constructor

从一些地方读到后,我感到困惑。

我正在做这个 page 的例子 假设有一个类(书),其中有一个对象(作者)作为其成员之一。这是构造函数:

Book::Book(string name, Author author, double price, int qtyInStock)
      : name(name), author(author) {   **// Must use member initializer list to construct object**
   // Call setters to validate price and qtyInStock
   setPrice(price);
   setQtyInStock(qtyInStock);
}

我试图在构造函数中声明对象作者而不是初始化程序 lisr。它给了我错误。 没有匹配的函数来调用 Author::Author() --> 这是 Author 的默认构造函数。


阅读这些 stackoverflow 帖子后:this1this2 我的理解是,从这 2 个中总结:

  • 当执行进入构造函数体时,一个对象被认为是必须完全初始化

  • 一个对象在初始化列表中初始化了它的所有成员。即使您没有在那里显式初始化它们,编译器也会很乐意为您完成

  • 像 int 或 double 这样的原生类型确实有一个默认构造函数

因此,根据以上所有这些,我的理解是用户定义的对象/类不会自动具有默认构造函数,这与原始类型不同。 这就是为什么它给出错误,如果我不使用成员初始化列表(调用复制构造函数),导致编译器尝试使用它(用户定义的类)没有的默认构造函数来初始化它。

因此可能的解决方案是:为类定义一个默认构造函数,或者使用成员初始化器


然后我读了这个post在 stackoverflow 上说: “一个类有多少默认方法?”答案提到 It HAS DEFAULT CONSTRUCTOR

1。如果它有默认构造函数,为什么我的第一个案例(书籍和作者类)会出错?

我也读到这个 ​​page ,假设我之前定义了一个类 Point,然后页面写道:

Point p1;       // **Invoke default constructor**
                // OR Point p1 = Point(); NOT Point p1();

2。那么当我们像上面那样声明时,它是否调用了默认构造函数?如果是这样,为什么不报错?我以为一个类没有默认构造函数?

如果你能帮我澄清一下,并回答上面的两个问题(斜体),我将不胜感激

最佳答案

完整的答案很大,在这里呈现:

http://en.cppreference.com/w/cpp/language/default_constructor

如果您专门创建一个,那么总会有一个默认构造函数。这包括可以接受但不必接受参数的构造函数 - 具有默认参数的构造函数和可变参数模板都可以是默认构造函数。

如果你将它标记为 = delete 那么它永远不会有一个。

否则,如果没有用户提供的构造函数存在,编译器将尝试为您创建一个,除非在某些情况下(完全列在上面的链接中的 Deleted implicitly-declared default constructor 部分)

  • T 有一个没有默认初始值设定项的引用类型成员。

  • T 有一个 const 成员,但没有用户定义的默认构造函数或默认成员初始值设定项(C++11 起)。

  • T 有一个成员(没有默认成员初始值设定项)(C++11 起),它有一个已删除的默认构造函数,或者它的默认构造函数不明确或无法从此构造函数访问。

  • T 有一个直接的或虚拟的基础,它有一个删除的默认构造函数,或者它是不明确的或无法从此构造函数访问。

  • T 有一个直接或虚拟基类,它有一个已删除的析构函数,或者一个无法从此构造函数访问的析构函数。

  • T 是一个非 union 类,其变体成员 M 具有非平凡的默认构造函数,并且包含 M 的匿名 union 的变体成员没有默认成员初始值设定项。

以及 union 类型的一些附加规则。

tl;dr:这很复杂。

关于c++ - C++ 类是否具有默认构造函数以及在以下情况下调用哪些构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39888921/

相关文章:

c++ - 友元函数和类的定义

javascript - 如何在空对象中添加新的键和值?

c++ - 无法在托管 C++ 中使用 new 关键字创建非托管对象

c++ - 使用 VS2012 编译器的 32 位 Qt5 构建中的 ICU 支持导致 Qt5 构建失败;因此 Webkit 也是不可构建的

Java - 从包含父类的对象中获取扩展类

java - 如何获取列表包含的元素类?

javascript - 对对象数组中相似的键求和

c++ - 自动矢量化 : Convincing the compiler that alias check is not necessary

C++:删除指针数组时出错

c++ - 使用 MergeCom 将私有(private)标记添加到 DICOM 时出现问题