宝杉的博客

UNIX/LINUX;ACE;SNMP;C++
posts - 33, comments - 23, trackbacks - 0, articles - 0

08-13复习

Posted on 2007-08-30 10:28 宝杉 阅读(181) 评论(0)  编辑 收藏 引用 所属分类: C++

 

析构函数

构造函数初始化表:构造函数特殊的初始化方式“初始化表达式表”(简称初始化表)。

初始化表位于函数参数表之后,却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体内的任何代码被执行之前。

规则

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

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

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

效率

1 内部成员:

初始化表和函数体内赋值都可以,但效率不完全相同,但后者更为清晰直观。

例子:

class F

{

 public:

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

 private:

    int m_x, m_y;

    int m_i, m_j;

}

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) 数据成员在函数体内被初始化

两种方式效率区别不大。

 

2 非内部成员:

只能用初始化表,提高效率。

例子:

    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;         // 成员对象

};

比较与分析:

B::B(const A &a)

 : m_a(a)          

{

   …

}

B::B(const A &a)

{

m_a = a;

}

1 B类构造函数的初始化里,调用了A类的拷贝构造函数。

2 B类构造初始化里,隐藏了以下几个步骤:

先创建了a对象,调用了A类的无参数构造函数;

把a赋值给m_a,调用了A类的赋值函数;

 

深入探讨:

构造和析构的次序?

构造从最深处的基类开始的,先一层层调用基类的构造函数,然后调用成员对象的构造函数。

而析构函数严格按照构造函数相反的次序执行,该次序唯一,以便让编译器自动执行析构函数。

特别之处是,成员对象初始化次序不受构造函数初始化表次序影响,由在类中声明的次序决定。而类声明是唯一的,构造函数却可能有多个,所以有多个不同次序函数初始化表。如果按照构造函数的次序构造,那么解析函数不能得到唯一的逆序。


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理