2011-08-24 45 views
3

我还在路上在C++中以启迪,让我承担......C风格的初始化列表,结构和类的构造函数

假设我有一个结构:

struct MyThing 
{ 
    int a, b; 
}; 

我看中使用C风格的速记创建一个,图1:

MyThing mt = { 1, 2 }; 

然后假设我决定在我的结构某处粘的方法,以及(是什么样的人,我是)我觉得结构并不适合方法,所以把它变成一个类:

class MyThing 
{ 
public: 
    int a, b; 
    int sum() 
    { 
     return a + b; 
    } 
}; 

我的Fig.1仍然正常工作 - 一切都是hunky dory。然后,我决定,我会最终需要的私有方法和成员:

class MyThing 
{ 
private: 
    int c; 
    void swap() { 
     c = a; 
     a = b; 
     b = c; 
    } 
public: 
    int a, b; 
    int sum() 
    { 
     return a + b; 
    } 
}; 

在这一点上,图1中的C风格的初始化列表编译失败(在VS反正)与“非聚集不能与初始化列表”初始化 - 这是很好的说明如下:http://msdn.microsoft.com/en-us/library/0s6730bb(v=vs.71).aspx

所以我切换到:

class MyThing 
{ 
private: 
    void swap() { 
     int c = a; 
     a = b; 
     b = c; 
    } 
public: 
    int a, b; 
    MyThing (int _a, int _b) : a(_a), b(_b) {} 
    int sum() 
    { 
     return a + b; 
    } 
}; 

然后换到图1(图2)

MyThing mt(1, 2); 

Sooooo,毕竟,我的问题是:是否有使用c样式初始化列表(即他们更快?)创造的东西?或者它首先要做的就是:

struct MyThing 
{ 
    int a, b; 
    MyThing(int _a, int _b) : a(_a), b(_b) {} 
}; 

并且从头开始使用它作为图2?是否有任何性能影响(即使它可忽略不计)?

谢谢!

+1

“是它们更快“ - 我会推荐使用任何最自然的方式,只有在真正遇到瓶颈时才更快地担心。如果你在一个紧密的循环中执行此操作,那么可能会有其他问题... – Flexo

+0

答案是“否”,它们没有比正确的初始化列表更快。 –

+0

@Minging Duck--这就是我刚刚得出的结论 - 虽然使用简写来创建事物可以节省打字时间,但是当它们嵌套时(即嵌套的POD结构),读取速度相当可怕 - 而且具有构造函数只有额外的输入是类名(使用()而不是{}) - 更清晰,因为发生了什么:) 现在我同意awoodland - 如果它成为一个问题,担心性能;这不太可能,如果我担心表现,我会创建许多不同的实例... 谢谢你的回答:) – Seb

回答

0

那么,首先,你说的例子失败了,其实是起作用的。 (直到添加构造函数才会失败)

现在请记住,一个对象只是一块内存。因此的

MyThing mt = { 1, 2 };  // Fig A 

二进制图像是完全一样

int mt[2] = { 1, 2};   // Fig B. 

因此实现图A或图B,编译器仅需要发射:

mt DW  0x0001  Fig C 
     DW  0x0002 

换句话说,零运行时间成本。

但是,如果ctor存在,那么它必须运行(这是合同C++承诺的一部分)。 (不可避免地运行时成本)

类似地,私有成员,基类等,用来处理编译时分配所需要的一对一的对应干扰,我们在图C.

+0

然而,如果构造函数是MyThing(int x,int y):x_(x),y​​_(y){}'并且是内联定义的,那么不可能有任何运行时开销。 –

+0

我不明白为什么私人会员有问题。为什么编译器根据其可见性区分不同的成员?私有成员仍然有自己独特的存储空间,编译器显然知道编译时的偏移量。我并不担心性能,我只是想更好地理解语言/编译器:) – Voo

+0

谢谢,我已经更新了示例,以便它*会*使编译器失败:) – Seb

0

使用c样式初始化列表(即他们更快?)创造的东西是否有任何好处?

更快,更慢,它真的很重要吗?它通常在语法上比调用构造函数更方便。这是C++ 0x允许你为所有对象使用这种语法的原因的一部分。

作为编译时优化,聚合初始化可能是免费的。编译器也可以优化简单的构造函数。要知道的唯一方法是查看生成的程序集。但除非你有实际的瓶颈,否则你不应该在意。