nit*_*ian 13 c++ performance constructor initializer-list
如果可能,构造函数应该通过初始化列表初始化其所有成员对象.它比通过构造函数体内的赋值构建构造函数更有效.
有人可以解释一下,为什么在一个例子的帮助下使用初始化列表更有效率?
Rob*_*obᵩ 14
考虑这个程序:
#include <iostream>
struct A {
A() { std::cout << "A::A()\n"; }
A(int) { std::cout << "A::(int)\n"; }
void operator=(const A&) { std::cout << "A::operator=(const A&)\n"; }
};
struct C1 {
A a;
C1(int i) {
a = i;
}
};
struct C2 {
A a;
C2(int i) : a(i) {}
};
int main() {
std::cout << "How expesive is it to create a C1?\n";
{ C1 c1(7); }
std::cout << "How expensive is it to create a C2?\n";
{ C2 c2(7); }
}
Run Code Online (Sandbox Code Playgroud)
在我的系统(Ubuntu 11.10,g ++ 4.6.1)上,程序产生以下输出:
How expesive is it to create a C1?
A::A()
A::(int)
A::operator=(const A&)
How expensive is it to create a C2?
A::(int)
Run Code Online (Sandbox Code Playgroud)
现在,考虑一下为什么这样做.在第一种情况下,C1::C1(int),a必须是默认构造之前C1的构造可以被调用.然后它必须分配给via operator=.在我的简单示例中,没有int可用的赋值运算符,因此我们必须构造A一个int.因此,不使用初始化程序的成本是:一个默认构造函数,一个int构造函数和一个赋值运算符.
在第二种情况下,C2::C2(int)只int调用构造函数.无论默认A构造函数的成本C2:C2(int)是多少,显然成本都不会高于成本C1::C1(int).
A:
void operator=(int) { std::cout << "A::operator=(int)\n"; }
Run Code Online (Sandbox Code Playgroud)
然后输出将显示:
How expesive is it to create a C1?
A::A()
A::operator=(int)
How expensive is it to create a C2?
A::(int)
Run Code Online (Sandbox Code Playgroud)
现在一般不可能说哪种形式更有效率.在您的特定类中,默认构造函数的成本加上赋值的成本比非默认构造函数更昂贵吗?如果是这样,则初始化列表更有效.否则就不是.
我写过的大多数类都会在init列表中更有效地初始化.但是,这是一个经验法则,并不一定适用于所有可能的情况.
好吧,否则你调用默认构造函数然后执行赋值.这是一个更长的步骤,取决于初始化的性质可能会变得非常低效.
因为它直接初始化,而不是默认初始化然后分配.对于POD来说,性能方面可能无关紧要,但如果类型构造函数正在进行繁重的工作,那么它将会成功.
此外,在某些情况下,您必须使用init列表,因此您应始终保持一致性.
| 归档时间: |
|
| 查看次数: |
3440 次 |
| 最近记录: |