今天被腾讯电话面试了,15分钟就被秒杀了,其中一个问题“为什么要用成员初始化列表”,我答不上来。回头自己总结了一下。
首先要知道,编译器确保所以成员对象在构造函数执行前被初始化,不论有没有成员初始化列表。代码如下,用Dev C++编译:
#include <iostream>
using namespace std ;
class A
{
public :
A() { cout << "A()" << endl ; }
A( int ) { cout << "A( int )" << endl ; } ;
} ;
class B
{
public :
A x ;
/* 分别执行这两个不同的构造函数,就可以发现x的初始化都是先于B()的执行!*/
B():x(3) { cout << "B()" << endl ; }
//B() { cout << "B()" << endl ; }
} ;
int main()
{
B b ;
system( "pause" ) ;
return 0 ;
}
使用成员初始化列表,有两个目的:一是必须如此,二是有更好的效率。
一、(1)成员本身是个类,并且只定义了带参数的构造函数,即没有默认的构造函数,只能用初始化列表来产生类的实例。如下,在Dev C++下编译不通过:
#include <iostream>
using namespace std ;
class A
{
public :
//A() { cout << "A()" << endl ; }
A( int ) { cout << "A( int )" << endl ; } ;
} ;
class B
{
public :
A x ;
//B():x(3) { cout << "B()" << endl ; }
B() { cout << "B()" << endl ; }
} ;
int main()
{
B b ;
system( "pause" ) ;
return 0 ;
}
(2) 常量成员只能用成员列表初始化,而不能给它“赋值”。如:
#include <iostream>
using namespace std ;
class A
{
public :
//A() { cout << "A()" << endl ; }
A( int ) { cout << "A( int )" << endl ; } ;
} ;
class B
{
public :
A x ;
const int y ;
// const int y = 0 ; // 不符合ISO 的标准,使用Dev C++ 编译的
B():x(3), y(0) { cout << "B()" << endl ; }
//B() { cout << "B()" << endl ; }
} ;
int main()
{
B b ;
system( "pause" ) ;
return 0 ;
}
二、更好的效率。
#include <iostream>
using namespace std ;
class A
{
public :
int x ;
A() { cout << "A()" << endl ; }
A( int ) { cout << "A( int )" << endl ; } ;
A& operator = ( int b )
{
x = b ;
cout << "A& operator = ( int b )" << endl ;
}
} ;
class B
{
public :
A a ;
//B():a(3) { cout << "B()" << endl ; }
/* 结果如下:
A( int )
B()
*/
B() { a = 10 ; cout << "B()" << endl ; }
/* 结果如下:
A()
A& operator = ( int b )
B()
*/
} ;
int main()
{
B b ;
system( "pause" ) ;
return 0 ;
}
可见,成员初始化列表没有调用赋值操作符,效率当然要高一下。
从上可知,成员初始化列表只有好处,没有坏处,自己也要养成这种习惯!