"when the member is then reinitialized re initialized otherwise in the constructor"教程中 cplusplus.com



我正在阅读cplusplus.com.中的课程教程

我被下面这段话弄糊涂了。

默认构造类的所有成员可能很方便,也可能总是不方便:在某些情况下,这是一种浪费(当成员在构造函数中重新初始化时(,但在其他一些情况下,默认构造甚至是不可能的(当类没有默认构造函数时(。在这些情况下,应在成员初始化列表中对成员进行初始化。

所以,我的问题是;当该成员然后在构造函数"中被重新初始化时;意思是为什么是浪费?

一开始,我认为;重新初始化,就像下面的代码一样。

class Son
{
int age;
public:
// default constructor
Son()
{
age = 1;
}
Son(int age) : age(age) {}
};
class Father
{
Son son;    // First, I think that it will call default constructor of class Son when the object of Father was created
int age;
public:
// Then object of Father will call this constructor, then initialize son again.
Father(int sonAge, int fatherAge) : son(sonAge), age(fatherAge)
{
}
};

然后,我发现Son son根本不是定义子,它只是等待Father的构造函数初始化son。所以这不是浪费,我的想法是错误的!!!也许我缺乏对物体创造顺序的了解?cplusplus.com提供的教程对我来说似乎不完整…

你能给我举几个代码示例吗?

在输入构造函数的主体之前,所有对象都已初始化,所以让我们逐步完成:

int age;
Son() // age initialized here (does nothing)
{
age = 1;// age assigned new value here
}

但是,如果年龄比int更复杂呢?如果它是一个建筑非常昂贵的班级呢?

Expensive age;
Son() // age initialized here takes a lot of time and resources
{
age = 1;// age assigned new value here. This requires construction of a 
// temporary Expensive (which takes a lot of time and resources)
// and then assigns the temporary to age (which may also be time and 
// resource-consuming), wasting the effort spent on the default 
// construction. The temporary is then destroyed, and that wastes 
// even more
}

如果使用成员初始化程序列表

Expensive age;
Son(): age(1) // age initialized here takes a lot of time and resources
{
// does nothing
}

注:以上是最坏的情况。Expensive可以有一个Expensive &operator=(int)来减少一些工作,但您仍然需要处理默认构造和赋值逻辑,而不是单个构造函数调用。另外,必须有人编写=重载,并且不存在的代码没有错误。

所以,我的问题是;当该成员然后在构造函数"中被重新初始化时;意思是

没有";重新初始化";。每个对象都只初始化一次(尽管初始化可能是真空,这意味着它实际上什么都不做;在某些情况下,在实际初始化之前没有初始化,这可能被视为两次初始化(。作者的意思是初始化后的赋值

在您的示例中,构造函数会发生这种情况

Son()
{
age = 1;
}

此构造函数没有成员初始化器,这意味着成员age(其声明中也没有默认初始化器(将被默认初始化。只有在初始化之后,才执行构造函数的主体并完成赋值age = 1;

现在,在这种情况下,基本上没有浪费,因为int的默认初始化不会做任何事情(它使值不确定(。然而,假设agestd::string,而分配是age = "1";。然后,您将首先调用std::string的默认构造函数以初始化age,然后"1"分配给age。第一个步骤是多余的,使用初始化器列表Son() : age("1") { }可以避免额外的步骤。(是否真的会有任何性能差异取决于许多因素,编译器可能足够好,可以将两者优化到相同的机器代码。(

一个问题是";初始化";它在口语中的用法与上述技术含义不同。通俗地说,它可以指一个变量第一次设置其值。在这种情况下,分配age = 1;将被视为初始化age,尽管这是分配,而不是初始化。当谈到一个变量未初始化时,这个意思最常被使用,从技术上讲,更正确的应该是的值不确定。

相关内容

  • 没有找到相关文章

最新更新