我有一个全局成员数据对象,在标题(对于类MyMainObj)中定义,如下所示。
class MyMainObj
{
MyDataObj obj;
}
MyDataObj
有一个默认构造函数。
何时MyDataObj
的构造函数被调用?
它是否被称为MyMainObj
的创建的一部分?
答案 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 order,Copy-construction initialization list,and 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)
进入对象构造函数后,已经为其分配了内存。然后执行顺序如下:
初始化列表中指定的基类构造函数(如果有);如果未指定,则使用默认构造函数。
成员数据的构造函数,在初始化列表中指定(默认情况下,如果未指定),按照它们在类定义中声明的顺序。它们在初始化列表中指定的顺序无关紧要。
构造函数体。
在问题中设置的示例中,输入 MyMainObj 的默认构造函数时将执行的第一件事是构建成员的 MyDataObj 的默认构造函数数据 obj 。