在C ++中是在对象创建之前或之后调用的构造函数吗?

时间:2015-12-21 16:18:56

标签: c++ constructor

我找到了关于java的这个问题的一些答案,但没有特别关于c ++。所以我在Java中读取了首先创建对象,然后调用构造函数。我想知道这是否与c ++相同?此外,如果是这种情况,那么具有默认构造函数的重点是什么?是继承目的吗?

9 个答案:

答案 0 :(得分:5)

"对象创建"用不同语言表示不同的东西。但在C ++中,最突出的问题是"对象生命周期何时开始?#34;。当一个对象的生命周期开始时,这意味着当它终止时(你删除它,或者如果它是一个堆栈对象,那么当它超出范围时),将会调用析构函数。

如果对象的生命周期没有正式开始,那么如果它稍后超出范围,则不会调用析构函数。

C ++解决了这个问题,如下所示:

  • 当你创建一个对象,比如类类型时,通过调用一个构造函数,首先分配内存,然后运行构造函数。
  • 当构造函数运行完成时,生命周期已经开始,析构函数将在结束时被调用。析构函数完成后,将释放内存。
  • 如果构造函数通过抛出异常而中止,则不会调用该对象的析构函数。但是,内存仍将被释放。

有关对象生命周期的更多信息,您可能需要查看,例如this question,或更好,在标准/好的教科书上。

基本思想是,在C ++中,我们尝试最小化分配内存和初始化之间的时间窗口 - 或者更确切地说,语言本身促进了“资源获取”的想法正在初始化"并且在不给它类型并初始化它的情况下获取内存是非常惯用的。通常编写代码时,例如如果你有一个A类型的变量,你可以把它想象成"这是指A的一块内存,其中A的构造函数成功运行到。完成#&34;您通常不必考虑"这是A大小的内存块的可能性,但构造函数失败,现在它是未初始化/部分初始化的无头blob。&# 34;

答案 1 :(得分:2)

这取决于你所说的“创造”。显然应该在创建对象之前分配内存。

但是正式地说,直到构造函数完成执行之后才创建对象(它的生命周期才开始)。如果构造函数没有完全执行(例如,发生了异常),则认为对象从不存在于第一位。例如,不会调用此对象的析构函数(就像任何现有对象一样)

当您输入构造函数体时,您可以确保成员是创建的(默认构造函数或构造函数初始化列表中传递的任何内容;适用于变量初始化的通常语言规则:标量变量的初始值未定义)。

当你考虑继承时,它会更复杂。当你输入构造函数体时,祖先部分已经是现有的对象:它们的构造函数已经完成,即使子节点无法正确构造它们,它们的析构函数也会被调用。

答案 2 :(得分:1)

<强>都不是。

对象创建过程包括构造函数调用。

拥有默认构造函数的目的是允许对象创建过程的这一部分成为无操作。还有什么呢?

答案 3 :(得分:1)

这里是顺序:首先,分配内存。然后调用任何基类构造函数。最后调用类构造函数。

如果您始终使用参数列表创建对象,则实际上并不需要默认构造函数。

答案 4 :(得分:1)

您似乎对条款感到困惑,但我会尝试定义一些(非官方)条款,以澄清此问题:

  1. 分配
    这是为对象分配内存的步骤。
  2. 初始化
    这是与语言相关的对象属性为&#34; set&#34;的步骤。 vTable和任何其他语言实现&#34;相关操作已经完成。
  3. 建筑
    现在分配并初始化了一个对象,正在执行构造函数。是否使用默认构造函数取决于对象的创建方式。
  4. 您可以在第3步之后考虑创建的对象

答案 5 :(得分:0)

是的,首先分配对象的内存,然后调用构造函数来实际构造内容。有点像建房子,你首先购买[或以其他方式合法获得许可]土地(记忆)建立它,然后开始建设。如果你反过来这样做,你可能会遇到麻烦。

当您的对象需要构造而没有参数时,使用默认构造函数。在某些情况下,这根本没有任何意义,但默认构造函数用于std::vector - 因为std::vector<myclass>将被实现为一个对象数组,如果你增长它[使用push_back],大小将加倍(或类似的东西),并且未使用的向量背面的对象将是默认构造的。

创建后需要构造所有对象(即使你没有声明一个,在这种情况下,你得到一个空的构造函数,如果编译器很聪明,它将不会调用构造函数,因为它不会做任何事情)

答案 6 :(得分:0)

术语“默认构造函数”仅表示不需要参数的构造函数,因此可以在默认情况下使用它。例如:

struct MyObject {
    MyObject() { ... }    // default constructor
    MyObject(int) { ... } // some other non-default constructor
};

int main()
{
    MyObject x;  // default constructor is called since you didn't give
                 // any explicit parameters.
    MyObject x2(5); // A non-default constructor is called.
}

请注意,术语“默认”并不意味着您尚未定义它。默认构造函数可能由您提供,也可能在某些情况下自动生成。您甚至可以使用默认默认构造函数:

struct MyObject {
    MyObject() = default; // defaulted default constructor
};

在这里,您告诉编译器使用默认实现生成默认构造函数。

无论它是否是默认构造函数,在构造函数体执行之前,对象的构造尽可能自动化。这意味着已分配内存以存储对象,已构造任何基类,并且已构造任何成员。该对象还采用了为RTTI和虚函数调用而构造的类的类型标识。

答案 7 :(得分:0)

  

此外,如果是这种情况,那么具有默认值的重点是什么   构造函数呢?

“默认构造函数”的目的是告诉程序应该如何构建没有参数的对象,换句话说 - 对象的“默认”状态是什么。

例如,std::unique_ptr的默认状态是指向null而没有服装删除器 字符串的默认状态是一个空字符串,大小为0 向量的默认状态是一个大小为0的空向量 默认状态T是构造函数T()指定的状态。

答案 8 :(得分:0)

认为由于资源分配问题,必须在创建对象后调用构造函数。对象只不过是具有函数指针(成员函数)和成员变量(属性)的结构。如果构造函数在将这些值分配到内存之前设置它们中的任何值,则会发生错误。

例如,构造函数将int值存储在对象的成员变量中,但是您的对象的成员变量尚未分配,因此无法成功存储该值。

问候!