当前位置:编程学习 > C/C++ >>

类的初始化列表如何提高程序效率

1:类的初始化列表是怎么提高效率的?
2:类的初始化列表是按照列表中出现的顺序来初始化的吗?
看下面的两个程序代码:
程序一

 

[cpp] 
class A 

public: 
  A(int t=0) 
  { 
      cout<<"construct A"<<endl; 
  } 
  A(const A &) 
  { 
      cout<<"copy A"<<endl; 
  } 
  A & operator =(const A &) 
  { 
      cout<<"equal"<<endl; 
      return *this; 
  } 
  ~A() 
  { 
      cout<<"destory A"<<endl; 
  } 
}; 
class B 

public: 
    A a; 
    B() 
    { 
        a=0; 
    } 
}; 
int main() 

    B b; 
    return 0; 

class A
{
public:
  A(int t=0)
  {
   cout<<"construct A"<<endl;
  }
  A(const A &)
  {
   cout<<"copy A"<<endl;
  }
  A & operator =(const A &)
  {
   cout<<"equal"<<endl;
   return *this;
  }
  ~A()
  {
   cout<<"destory A"<<endl;
  }
};
class B
{
public:
 A a;
 B()
 {
  a=0;
 }
};
int main()
{
    B b;
 return 0;
}程序二
[cpp] 
class A 

public: 
  A(int t=0) 
  { 
      cout<<"construct A"<<endl; 
  } 
  ~A() 
  { 
      cout<<"destory A"<<endl; 
  } 
}; 
class B 

public: 
    A a; 
    B():a(0) 
    { 
    } 
}; 
int main() 

    B b; 
    return 0; 

class A
{
public:
  A(int t=0)
  {
   cout<<"construct A"<<endl;
  }
  ~A()
  {
   cout<<"destory A"<<endl;
  }
};
class B
{
public:
 A a;
 B():a(0)
 {
 }
};
int main()
{
    B b;
 return 0;
}程序一与程序二的运行结果是不同的,程序一中多了一次构造与析构函数,赋值函数的调用,这就是初始化列表提高效率的地方
程序一在编译器器层被转化成了
[cpp]
B() 

    //以下代码不可实际运行,只是说明问题  
    a.A::A(0);//调用A的构造函数  
    A tmp(0);//产生一个临时的对象  
    a=tmp;//通过赋值运算符将临时对象赋给a  
    tmp.A::~A;//释放临时对象的空间  

 B()
 {
  //以下代码不可实际运行,只是说明问题
  a.A::A(0);//调用A的构造函数
  A tmp(0);//产生一个临时的对象
  a=tmp;//通过赋值运算符将临时对象赋给a
  tmp.A::~A;//释放临时对象的空间
 }下面是相应的汇编代码:可以发现和上面的过程分析是一样的,有兴趣可以自已研究下
[cpp]
00401227   call        @ILT+15(A::A) (00401014) 
0040122C   mov         dword ptr [ebp-4],0 
29:       { 
30:           a=0; 
00401233   push        0 
00401235   lea         ecx,[ebp-14h] 
00401238   call        @ILT+15(A::A) (00401014) 
0040123D   mov         byte ptr [ebp-4],1 
00401241   lea         eax,[ebp-14h] 
00401244   push        eax 
00401245   mov         ecx,dword ptr [ebp-10h] 
00401248   call        @ILT+0(A::operator=) (00401005) 
0040124D   mov         byte ptr [ebp-4],0 
00401251   lea         ecx,[ebp-14h] 
00401254   call        @ILT+120(A::~A) (0040107d) 
31:       } 

00401227   call        @ILT+15(A::A) (00401014)
0040122C   mov         dword ptr [ebp-4],0
29:       {
30:           a=0;
00401233   push        0
00401235   lea         ecx,[ebp-14h]
00401238   call        @ILT+15(A::A) (00401014)
0040123D   mov         byte ptr [ebp-4],1
00401241   lea         eax,[ebp-14h]
00401244   push        eax
00401245   mov         ecx,dword ptr [ebp-10h]
00401248   call        @ILT+0(A::operator=) (00401005)
0040124D   mov         byte ptr [ebp-4],0
00401251   lea         ecx,[ebp-14h]
00401254   call        @ILT+120(A::~A) (0040107d)
31:       }程序二在底层被转化成了[cpp] view plaincopyprint?
B():a(0) 

    a.A::A(0); 

 B():a(0)
 {
  a.A::A(0);
 }可以发现通过初始化列表在申请了对象a的空间后直接调用初始化列表中指定的构造函数来构造成员对象,因此少了很多中间步骤,因此提高了程序的效率:)
这是程序二对应的汇编代码(看看就知道了吧:)):
[cpp] 
0040120A   mov         dword ptr [ebp-4],ecx 
0040120D   push        0 
0040120F   mov         ecx,dword ptr [ebp-4] 
00401212   call  &nbs

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,