原创 高质量C++/C编程指南 -- 第9章 类的构造函数、析构函数与赋值函数2

2008-10-28 11:55 1880 7 7 分类: 软件与OS

9.2 构造函数的初始化表
构造函数有个特殊的初始化方式叫“初始化表达式表”(简称初始化表)。初始化表位于函数参数表之后,却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体内的任何代码被执行之前。


构造函数初始化表的使用规则:


u 如果类存在继承关系,派生类必须在其初始化表里调用基类的构造函数。


例如


class A


{…


A(int x); // A的构造函数


};


class B : public A


{…


B(int x, int y);// B的构造函数


};


B::B(int x, int y)


: A(x) // 在初始化表里调用A的构造函数


{



}


u 类的const常量只能在初始化表里被初始化,因为它不能在函数体内用赋值的方式来初始化(参见5.4节)。


u 类的数据成员的初始化可以采用初始化表或函数体内赋值两种方式,这两种方式的效率不完全相同。


非内部数据类型的成员对象应当采用第一种方式初始化,以获取更高的效率。例如


class A


{…


A(void); // 无参数构造函数


A(const A &other); // 拷贝构造函数


A & operate =( const A &other); // 赋值函数


};



class B


{


public:


B(const A &a); // B的构造函数


private:


A m_a; // 成员对象


};



示例9-2(a)中,类B的构造函数在其初始化表里调用了类A的拷贝构造函数,从而将成员对象m_a初始化。


示例9-2 (b)中,类B的构造函数在函数体内用赋值的方式将成员对象m_a初始化。我们看到的只是一条赋值语句,但实际上B的构造函数干了两件事:先暗地里创建m_a对象(调用了A的无参数构造函数),再调用类A的赋值函数,将参数a赋给m_a。



B::B(const A &a)


: m_a(a)


{



}
B::B(const A &a)


{


m_a = a;



}


示例9-2(a) 成员对象在初始化表中被初始化 示例9-2(b) 成员对象在函数体内被初始化



对于内部数据类型的数据成员而言,两种初始化方式的效率几乎没有区别,但后者的程序版式似乎更清晰些。若类F的声明如下:


class F


{


public:


F(int x, int y); // 构造函数


private:


int m_x, m_y;


int m_i, m_j;


}


示例9-2(c)中F的构造函数采用了第一种初始化方式,示例9-2(d)中F的构造函数采用了第二种初始化方式。



F::F(int x, int y)


: m_x(x), m_y(y)


{


m_i = 0;


m_j = 0;


}
F::F(int x, int y)


{


m_x = x;


m_y = y;


m_i = 0;


m_j = 0;


}


示例9-2(c) 数据成员在初始化表中被初始化 示例9-2(d) 数据成员在函数体内被初始化

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条