类的初始化列表如何提高程序效率
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++ ,