2015-02-09 327 views
12

关于以下内容,是否有任何理由对另一个做一个或者它们大致相同?C++ - 在头文件中初始化变量与构造函数

class Something 
{ 
    int m_a = 0; 
}; 

VS

class Something 
{ 
    int m_a; 
    Something(int p_a); 
}; 

Something::Something(int p_a):m_a(p_a){ ... }; 
+4

第一个是C++ 11 – Emadpres 2015-02-09 15:25:02

+0

我不指望第一代码工作的新功能。 (编辑:确定它现在执行) – Aitch 2015-02-09 15:25:11

+1

[C++ 11的可能重复允许非静态和非const成员的类内初始化。什么改变?](http://stackoverflow.com/questions/13662441/c11-allows-in-class-initialization-of-non-static-and-non-const-members-what-c​​) – 2015-02-09 15:37:42

回答

5

第一种形式是新的C++ 11所以在这一点上并不十分良好的支持,特别是如果你需要支持各种老版本编译的。

否则,当C++ 11编译器可用时,它们应该大致相当。

+0

我以为我们'我总是能够像第一种形式一样初始化'int'。 C++ 11现在是否支持以这种方式初始化多个int?!? – 2015-02-09 15:32:16

+0

@Jonathan Mee你总是可以以前面的方式初始化'静态'整数,是的。 – 2015-02-09 15:35:10

+1

@JonathanMee:非静态成员初始化对于C++ 11来说是新的。它还将静态成员初始化扩展为任何常量字面类型,而不仅仅是整数。 – 2015-02-09 15:38:52

9

如果您有多个构造函数(并且希望它们都以相同方式初始化成员),或者如果您不需要编写构造函数,则第一种形式更方便。

如果初始化程序依赖于构造函数参数,或者对于类内初始化过于复杂,则需要第二个参数;如果构造函数复杂,可能会更好,将所有初始化保存在一个地方。 (和它的也需要,如果您有支持前C++ 11级的编译器。)

0
class Something 
{ 
    int m_a = 0; 
}; 

相当于

class Something 
{ 
    int m_a(0); 
}; 

所以,做

class Something 
{ 
    int m_a;// (0) is moved to the constructor 
public: 
    Something(): m_a(0){} 
}; 

产生一个统一的语法用于需要或不需要运行时输入的初始化。

个人而言,我不喜欢第一种形式,因为它看起来像是“声明然后转让”,这是完全的误解。

+1

除了在这种情况下'int m_a(0);'是不允许的。 – juanchopanza 2015-02-09 16:03:37

+0

详细说明,只有'= value;'和'{value};'被允许用于类内成员初始值设定项,而不是'(value);'。 – chris 2015-02-09 16:08:29

16

您发布的两个代码片段是不完全相同

class Something 
{ 
    int m_a = 0; 
}; 

这里指定在编译时初始化的值,即0

class Something 
{ 
    int m_a; 
    Something(int p_a); 
}; 

Something::Something(int p_a):m_a(p_a){ ... }; 

在这里,你做这件事运行时(或可能在运行时),与价值p_a不知道,直到调用构造函数。

下面这段代码更接近你的第一个例子:

class Something 
{ 
    int m_a; 
    Something(); 
}; 

Something::Something() : m_a(0) { /* ... */ }; 

,你必须考虑在这里是什么,在第一种情况下,该值在类定义直接出现。这可能会造成不必要的依赖。如果您需要0更改为1以后会发生什么情况?在其他形式的初始化将避免它的情况下,直接在类定义中(因此通常在头文件中)公开该值可能会导致大量代码的重新编译,因为Something::Something() : m_a(0)部分将被整齐地封装在源中文件并且不出现在头文件中:

// Something.h - stable header file, never changed 
class Something 
{ 
    int m_a; 
    Something(); 
}; 

// Something.cpp - can change easily 
Something::Something() : m_a(0) { /* ... */ }; 

当然,课堂初始化的好处可能远远超过这个缺点。这取决于。你只需要记住它。

+0

对于无意造成昂贵的重新编译的问题,这些代码很快就会变得相当昂贵。 – 2016-11-13 12:05:40

1

详细阐述Christian Hackl的答案。

第一种形式允许初始化m_a并同时具有默认c'tor。或者你甚至可以在你的代码,并明确定义构造函数与default关键字:

class Something 
{  
    int m_a = 0; 

    // explicitly tell the compiler to generate a default c'tor 
    Something() = default; 
}; 

随着第二种形式,自动生成的默认c'tor会离开m_a未初始化的,所以如果你想初始化一个硬编码值,你必须写自己的默认c'tor:

class Something 
{ 
    int m_a; 

    // implement your own default c'tor 
    Something() : m_a(0) {} 
};