何时调用成员数据构造函数?

时间:2009-10-15 17:16:35

标签: c++ constructor

我有一个全局成员数据对象,在标题(对于类MyMainObj)中定义,如下所示。

class MyMainObj
{
    MyDataObj obj;
}

MyDataObj有一个默认构造函数。 何时MyDataObj的构造函数被调用? 它是否被称为MyMainObj的创建的一部分?

7 个答案:

答案 0 :(得分:3)

使用该代码,obj不是MyMainObj的成员 - 它只是该构造函数中的本地对象。因此,它只会在/如果调用该构造函数时构造。

答案 1 :(得分:3)

关于你的代码,你有一个带变量的函数。进入函数后,您将运行声明变量的代码行,然后运行构造函数。

但你说“创造MyMainObj”。它是一个函数,它只能被调用,而不能被创建。


这一切都与标题问题有关,“成员什么时候构建?”如果MyMainObj是一个类而不是一个函数,这将适用。

您的成员对象按照它们在类声明中出现的顺序构造。进入构造函数后,所有对象都是完整构造的。 (但这不包括班级本身!)

也就是说,当类进入其构造函数时,所有成员都已完成构造函数。

在析构函数中(在析构函数运行之后)以相反的顺序销毁对象。

在伪图中:

MyClass
    Member1
    Member2
    Member3

Construction:
    Member1
    Member2
    Member3
    MyClass

Destruction:
    MyClass
    Member3
    Member2
    Member1

您可以使用初始化列表手动调用成员构造函数:

class foo
{
public:
    foo(void) : i(0) // construct i with 0.
    {
    }

    int i;
};

关于初始化列表,有各种各样的问题。 Initialization list orderCopy-construction initialization listand more

答案 2 :(得分:2)

在这种情况下,MyDataObj不是MyMainObj的成员,它是一个局部变量。

但是,在类的构造函数中调用数据成员的构造函数。在执行到达构造函数的第一行之前调用每个成员的默认构造函数,除非使用初始化列表显式指定构造函数,在这种情况下调用构造函数代替。

答案 3 :(得分:0)

是的,只要创建了MyMainObj实例,就会调用构造函数。

我对“全局成员”术语感到有点困惑 - 你声明该对象的方式它将是构造函数中的局部变量。我在这里错过了什么吗?

答案 4 :(得分:0)

鉴于课程A

class A {
    MyDataObj obj;
}

如果你没有为A编写构造函数,编译器会为你创建一个构造函数,这将创建obj作为构造A的一部分(并销毁obj }作为销毁A的一部分。

如果您为A编写构造函数,那么在构造函数运行之前将创建obj,尽管您可以重新分配它:

class A {
    MyDataObj obj;
  public:
    A() { } // obj created, but the value may or may not be predictable
}

class AA {
    MyDataObj obj;
  public:
    AA()
    {
        obj = MyDataObj(5);
    }
}

class AAA {
    MyDataObj obj;
  public:
    AAA() : obj(5) { } // member initializer list, my preferred method
}

使用第三个选项,数据对象在成员初始化程序列表运行之前创建,并且值按照它们在AAA中声明的顺序分配, NOT 它们的顺序列在成员初始化列表中。

UPDATE :创建和初始化之间存在差异。数据成员(以及基类和基类的数据成员)的空间总是被搁置 - 我称之为“创建”。但是,这并不意味着有用的值存储在该内存中。 There are separate rules for whether an object is default initialized,它取决于数据成员的类型(原始,POD,非POD),以及IIRC,主要对象的存储类(本地,静态,全局)。避免这方面意外的最简单方法是确保明确初始化所有内容。

答案 5 :(得分:0)

是的,正如其他声明的那样,成员将在构造时创建所有者类(由编译器生成或由提供的构造函数生成)。

创建顺序与您的成员在类声明中的表达方式相同。例如:

class MyType
{
    Thing a;
    Thing b;
    Thing d;
    Thing c;
 };

无论使用什么构造函数,无论初始化列表中的顺序如何,都将按以下顺序构造成员:a,b,d,c。一旦完成,构造函数代码将被执行(如果它存在),然后才会构造整个对象。

答案 6 :(得分:0)

进入对象构造函数后,已经为其分配了内存。然后执行顺序如下:

  1. 初始化列表中指定的基类构造函数(如果有);如果未指定,则使用默认构造函数。

  2. 成员数据的构造函数,在初始化列表中指定(默认情况下,如果未指定),按照它们在类定义中声明的顺序。它们在初始化列表中指定的顺序无关紧要。

  3. 构造函数体。

  4. 在问题中设置的示例中,输入 MyMainObj 的默认构造函数时将执行的第一件事是构建成员的 MyDataObj 的默认构造函数数据 obj