【问题标题】:Does the constructor creates objects of a class?构造函数是否创建类的对象?
【发布时间】:2018-07-25 13:29:49
【问题描述】:

我在看书

Robert Lafore 的 C++ 中的面向对象编程 并提到(第 235 页)

"如果没有构造函数,编译器会自动在程序中内置一个隐式的无参数构造函数,并且是这个构造函数创建了对象,即使我们没有定义它在类中。这个无参数的构造函数称为默认构造函数。如果它不是由构造函数自动创建的,您将无法创建没有定义构造函数的类的对象。”

构造函数是否创建对象?

我了解构造函数可用于初始化对象。但即使我不需要初始化我正在创建的类的对象,编译器也会生成一个默认构造函数。因此,我怀疑构造函数还有其他用途/需要。有吗?

【问题讨论】:

  • 如果不通过调用构造函数,你还能如何创建对象?
  • 关于构造函数的术语有点误导(恕我直言)。构造函数实际上并不constructcreate 对象,在调用构造函数时对象已经创建。构造函数真正做的是初始化已经创建的对象。
  • 构造函数初始化对象,也就是初始化成员等。它并没有真正为它分配内存等,这是之前完成的。关于总有一个构造函数的事实是因为让生活更轻松,语言更容易解析
  • 据我所知,它实际上只是一个初始化器,如果不需要初始化,它可以被优化掉。就像你有一块 (void*) 内存一样,你应该能够在不调用构造函数的情况下将它转换为一个普通对象,并且该对象应该可以正常工作(如果它确实需要构造,那么你需要通过placement-new调用该内存块上的构造函数。
  • @pasha 我推荐 C++ Primer,第 5 版,而不是您正在阅读的版本;它也是the definitive C++ book guide and list 的一部分。

标签: c++ constructor default-constructor


【解决方案1】:

构造函数是否创建类的对象?

不,它只是将类的成员初始化为某个有效的初始状态。为对象分配空间不是它的职责。

因此,我怀疑构造函数还有其他用途/需要。有吗?

不,类可以在没有任何构造函数的情况下存在;即使没有编译器提供一个。一个例子(live here):

struct A {
    A() = delete;  // prevent the compiler-provided default constructor
    int x;
};

int main() {
    A a = {1};     //    OK: aggregate initialization
    A b;           // Error: use of deleted function
}

当没有为类定义构造函数时,成员将保留default initialized,对于基元将是未定义的(垃圾),对于自定义类型的对象将调用它们各自的默认构造函数,这些构造函数可能会或可能不会初始化物体。这种行为是编译器提供的默认构造函数(称为trivial default constructor)所展示的:它只是名义上的,但没有做任何事情。

然而,我们不是说类没有构造函数,而是说它有一个默认构造函数,它不应该与用户提供的可以进行适当初始化的默认构造函数相混淆。请记住,默认构造函数只是一个可以使用零参数调用的构造函数,无论用户是否提供。

有些人可能认为 constructorinitializer 的误称,但他们部分正确。然而,语言的创造者也有一部分是正确的,因为从(内存的)原始位开始,对象的概念只有在构造函数完成之后才会存在。它通过将对象的状态设置为一些有效值来从原始内存构造对象,从而给出一致对象的概念。

【讨论】:

    【解决方案2】:

    构造函数是否创建对象?

    创建对象时会做两件事。

    • 为对象分配内存
    • 对象的初始化。

    说构造函数创建对象有点误导。对构造函数的调用只是完成初始化部分。例如,当您定义一个自动变量时:

    Classname instance;
    

    编译器在进入对象块时负责为对象分配内存,并在执行到达变量声明时调用构造函数。

    从技术上讲,为对象分配空间就足够了如果类型是“Plain Old Data”,但在 C++ 中强烈建议使用构造函数进行初始化。

    因此我怀疑构造函数还有其他用途/需要。

    正如您所提到的,构造函数的使用是将对象初始化为有效状态。

    但是当我使用复制赋值时,不会调用任何构造函数吗?

    使用复制赋值时不使用构造函数。但是,当您使用复制分配时,您分配给的对象已经创建,并且在发生这种情况时调用了构造函数。

    对于A类,A a; A b=a;...在这种情况下,构造函数会被调用多少次?

    两次。 A a 这里使用了默认构造函数。 A b=a 这里使用了复制构造函数。 b 被复制初始化。此示例中没有复制分配。

    A b(a); A b = a;这些都调用不同的运算符/函数吗?

    没有。他们都调用复制构造函数。第一个是显式调用复制构造函数,第二个是复制初始化。

    【讨论】:

    • 但是当我使用复制赋值时,不会调用构造函数吗?
    • @pasha:“复制分配”只能用于将对象的一个​​实例的值分配给另一个。因此,两者都已经存在并且它们的构造函数更早被调用。如果您使用复制构造,则调用(隐式或显式)复制构造函数。
    • 对于A类,A a; A b=a;...在这种情况下,构造函数会被调用多少次?
    • @pasha 语句 int x = 20x=30 之间存在差异;
    • A a; 调用默认构造函数。 A b=a; 调用复制构造函数(不是复制赋值运算符)。 b = a 调用复制赋值运算符(不是复制构造函数)。
    猜你喜欢
    • 1970-01-01
    • 2013-06-20
    • 2017-09-05
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2012-02-05
    • 1970-01-01
    相关资源
    最近更新 更多