由于构造函数初始化列表导致的优化 [英] Optimization due to constructor initializer list

查看:117
本文介绍了由于构造函数初始化列表导致的优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


如果可能,构造函数应通过
初始化列表初始化其所有成员对象。它比在构造函数体中通过赋值建立
构造函数更有效。


有人可以解释,为什么

解决方案

考虑使用这个程序:

  #include< iostream> 

struct A {
A(){std :: cout< A :: A()\\\
; }
A(int){std :: cout<< A::( int)\\\
; }
void operator =(const A&){std :: cout<< A :: operator =(const A&)\\\
; }
};

struct C1 {
A a;
C1(int i){
a = i;
}
};

struct C2 {
A a;
C2(int i):a(i){}
};

int main(){
std :: cout< 如何expesive是它是创建一个C1?\\\
;
{C1 c1(7); }
std :: cout<< 创建C2有多昂贵?\\\
;
{C2 c2(7); }在我的系统(Ubuntu 11.10,g ++ 4.6.1)上,程序(程序)生成此输出:

 创建C1有多大expesive? 
A :: A()
A::( int)
A :: operator =(const A&)
创建C2有多昂贵?
A::( int)

现在,考虑为什么这样做。在第一种情况下, C1 :: C1(int) a 必须在 C1 的构造函数可以被调用。然后必须通过 operator = 分配。在我的小例子中,没有 int 赋值运算符可用,因此我们必须从int中构造一个 A 。因此,不使用初始化器的成本是:一个默认构造函数,一个 int 构造函数和一个赋值运算符。



<在第二种情况下, C2 :: C2(int),只有 int 构造函数被调用。无论默认 A 构造函数的成本是多少,显然 C2:C2(int)的成本不大比成本 C1 :: C1(int)





或者,考虑这个选择。假设我们向 A 中添加以下成员:

  void operator = (int){std :: cout< A :: operator =(int)\\\
; }

然后输出将读为:

 创建C1的expesive是多少? 
A :: A()
A :: operator =(int)
创建C2有多昂贵?
A::( int)

现在是不可能说的高效。在你的特定类中,是默认构造函数的成本加上赋值的成本比非默认构造函数更昂贵?如果是这样,则初始化列表更有效。



我编写的大多数类都会在init列表中更有效地初始化。但是,这是一个经验法则,可能不是真的在每一个可能的情况。


Constructors should initialize all its member objects through initializer list if possible. It is more efficient than building the constructors via assignment inside the constructor body.

Could someone explain, why it is more efficient to use the initializer list with the help of an example?

解决方案

Consider this program:

#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); }
}

On my system (Ubuntu 11.10, g++ 4.6.1), the program produces this output:

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)

Now, consider why it is doing that. In the first case, C1::C1(int), a must be default-constructed before C1's constructor can be invoked. Then it is must assigned to via operator=. In my trivial example, there is no int assignment operator available, so we have to construct an A out of an int. Thus, the cost of not using an initializer is: one default constructor, one int constructor, and one assignment operator.

In the second case, C2::C2(int), only the int constructor is invoked. Whatever the cost of a default A constructor might be, clearly the cost of C2:C2(int) is not greater than the cost of C1::C1(int).


Or, consider this alternative. Suppose that we add the following member to A:

void operator=(int) { std::cout << "A::operator=(int)\n"; }

Then the output would read:

How expesive is it to create a C1?
A::A()
A::operator=(int)
How expensive is it to create a C2?
A::(int)

Now is is impossible to say generally which form is more efficient. In your specific class, is the cost of a default constructor plus the cost of an assignment more expensive than a non-default constructor? If so, then the initialization list is more efficient. Otherwise it isn't.

Most classes that I've ever written would be more efficiently initialized in an init list. But, that is a rule-of-thumb, and may not be true for every possible case.

这篇关于由于构造函数初始化列表导致的优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆