您的位置:首页 > 编程语言 > C语言/C++

关于C++——理解C++默默编写并调用了哪些函数&&函数初始化式(初始化列表相关)

2013-08-28 22:54 423 查看
如:

class Empty

{

};

实际上等于写了:

class Empty

{

          Empty()  { ... };//默认构造函数

         Empty( const Empty &rhs)  { ... };//复制构造函数

         ~Empty()  { ... };//析构函数, 编译器产出的析构函数是非可见的

        Empty & operator = (const Empty &rhs)  { ... };//赋值操作符

};

注:编译器可以暗自为class创建默认构造函数,复制构造函数,赋值操作符和析构函数。

 

 

构造函数可以包含一个构造函数初始化列表:

初始化列表一个冒号开始,接着以一个逗号间隔的数据成员列表,每个数据成员后面跟一个放在圆括号中的初始化式。

形如:

A :: A(const string &book)  :  isbn(book), units_sold(0), revenue(0)

{

       .......

}

这个构造函数将isbn成员初始化为book形参的值,将units_sold和revenue初始化为0。构造函数可以定义在类的内部或外部,但是构造函数初始化式只在构造函数的定义中而不是声明中指定。

从概念上讲,构造函数分为两个阶段执行:

(1)初始化阶段; (2)普通的计算阶段。计算阶段由构造函数体中所有语句组成。

不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化阶段发生在计算阶段之前。

如果没有为类成员提供初始化式,则编译器会隐式的使用成员类型的构造函数,如果那个类没有默认构造函数,则编译器尝试使用默认构造函数会失败。在这种情况下,为了初始化数据成员,必须提供初始化式。

没有默认构造函数的类类型的成员,以及const或引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。

例如:

class    A

{

        public:

                  A(int i);

        private:

                  int j;

                 const int k;

                 int  &r;            

}

//初始化(函数体内部实现不是初始化列表)

A :: A(int i)

{

        j = i;// ok

       k = i;//错误

       r = i;//错误

}

注:可以初始化const对象或引用类型的对象,但不能对它们进行赋值。在开始执行构造函数的函数体之前,要完成初始化。初始化const或引用类型数据成员的唯一机会是在构造函数初始化列表中。正确方式为:

A :: A (int i) : j(i),  k(i), ri(j)

{

   .....

}

成员初始化的次序:

1.成员被初始化的次序就是定义(声明)成员的次序,第一个成员首先被初始化,然后是第二个,依次类推。

2.如果一个成员根据其它成员而初始化,则成员初始化的次序至关重要。

Class X

{

      int i;

      int j;

     public :

            X(int val) : j(val), i(j)

            {

                 ....

            }

}

在上面这种情况下构造函数初始化列表看起了似乎是用val初始化j,然后用j再来初始化i。然而i首先被初始化,这里是用尚未初始化的j来初始化i

注:按照与成员声明一致的次序编写构造函数初始化列表,尽可能避免使用成员初始化其它成员。

下面的构造函数更好,不会出现由于初始化次序而引起的问题:

X(int val) : i(val), j(val)

{

    ....

}

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: