2015-02-23 118 views
2

所以,我刚刚阅读了关于构造函数初始值设定项以及为什么它们很重要。关于构造函数的问题

所以,在这方面,我问这只是因为它没有被明确提及,我不想弄错事情。

因此,在非初始化构造的情况下,例如:

Student(int i, string s) { 
    id = i; 
    name = s; 
} 

当构造函数被调用(创建一个实例时自动),做会员ID和名称首先获得初始化为默认int和string的值(以及那些默认值?)在进入构造函数的主体之前,当输入正文时,它们分别被i和s覆盖。我的解释是否正确?

如果是这样的话,然后初始化构造类似如下:

Student(int i, string s) : id(i), name(s) {} 

至高无上,应使用所有的时间,对不对?

为什么在这种情况下,其他的构造函数都是教导的?

+0

初始化很复杂:http://en.cppreference.com/w/cpp/language/initialization – Deduplicator 2015-02-23 02:56:51

+0

第一个可能是先教会的,因为它比较容易理解。在这之前,每个人都看到了分配,但不是奇怪的':'语法。一旦他们理解了构造函数,你就可以向他们展示':'语法。 – immibis 2015-02-23 03:07:12

回答

2

基本数据类型未初始化。对象是使用其默认构造函数创建的。

在您的示例中,它们确实被新值覆盖。取决于类型,这可能是低效的,因为在其默认构造函数中完成的工作可能会被浪费。在基本类型的情况下,编译器可以优化初始化,并且在std::string(您应该通过const reference btw传递)的情况下,与复制字符串的开销相比,它有一个相对便宜的默认构造函数。所以虽然初始化列表应该是首选样式,但不使用它在这种情况下并不是非常糟糕。

你有一个构造函数的原因是因为你可能有比复制一些数据或将它们赋值为简单值更复杂的逻辑。尝试创建自己的字符串类,它需要一个const char *参数。

+0

“使用其默认构造函数创建对象”:如果他们有一个,当然。 – Deduplicator 2015-02-23 02:58:13

+0

@Deduplicator你说得对,我没有想到POD。为什么不在你的评论中提及,以帮助我? – 2015-02-23 02:59:40

+0

@ KW123当您按值传递变量时,它将被复制。为什么要复制两次而不是一次? – 2015-02-23 03:06:04

0

是的你是对的。编译器会给它们默认值。数字类型为零,字符串为空,向量为空,布尔值为假,等等。这就是为什么在初始化列表之外初始化会带来性能损失:编译器首先进行初始化,然后分配值。此外,使用{}进行初始化也会检查正确的数据类型。如果你这样做myInteger {2.5}你会得到一个错误,但是如果你这样做myInteger = 2.5,你只能在变量中加2。关于对象,编译器将使用它们的默认构造函数。

+0

您的“默认值”正在描述值初始化,但这不会在这里发生。 – 2015-02-23 05:37:12

0
sample::sample(int a) 
{ 
    cout<< anim; 
    anim = a; 
    cout<< anim; 
} 

当调用

sample *Anim = new sample(10); 

输出将是:由编译器分配

0(grabage值。你不应该从一个未初始化的变量来读,没有任何规则,它将使0一如既往,它会打印一些垃圾值只)

sample::sample(int a) : anim(a) 
{ 
    cout<< anim; 
    anim = a; 
    cout<< anim; 
} 

输出将是:

10(值我们正在分配)

在前一种情况下,在anim = a处发生的值初始化,即datamember int anim是使用一些垃圾值创建的,并初始化为a,在创建datamember时发生后面的情况初始化。

+1

声明布尔值默认为true是完全错误的,值得赞扬。此代码实际上会导致未定义的行为。 – 2015-02-23 03:37:23

+1

不,我不是在声称,我只是为目前的情况解释它,对不起,忘了补充说 – 2015-02-23 05:18:43

+0

它仍然是未定义的行为。比简单地在变量中留下垃圾更糟糕的事情可能发生。价值可能会自己改变...或者更糟。您绝不能从未初始化的变量中读取数据。 – 2015-02-23 05:36:01