C++成员变量的初始化方式

来源:互联网 发布:网络词汇 编辑:程序博客网 时间:2024/05/29 04:03
    1.首先把需要初始化的成员变量分为几类:

变量(int)

静态变量(static int)

常量(const int )

静态常量(static const int)

 

     2.对应的初始化方式是:

一般变量可以在初始化列表里或者构造函数里初始化,不能直接初始化或者类外初始化

静态成员变量必须在类外初始化

常量必须在初始化列表里初始化

静态常量必须只能在定义的时候初始化

     3.举一个简单的例子

#include <iostream> 
#include <string> 
using namespace std; 
class Test 

private: 
    int a; 
    static int b; 
    const int c; 
    static const int d=4;                                       //静态常量--定义的同时初始化
public: 
    Test():c(3)//,a(1)或者在初始化列表里初始化 //常量const--初始化列表(并不是构造函数)
    { 
        a=1; 
    } 
}; 


int Test::b=2;                                                 //静态变量static

void main() 

    Test t; 
}

4.初始化成员数据的方法

C++初始化类成员时,是按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序

C++初始化的方式包括构造函数内部赋值初始化方法和构造函数初始化列表的方法

class CExample 

{
public:
    
int a;
    
float b;


    
//构造函数初始化列表-------------------------------A
    CExample(): a(0),b(8.8){}


    

//构造函数内部赋值一--------------------------------B1
    CExample()

          

{a=0;
             b
=8.8;}

       //构造函数内部赋值二---------------------------------B2

        CExample(int m,int n)

            {a=m;
           b
=n;}

};

PS:关于构造函数初始化列表的几点说明:

在初始化列表中需要注意的:

 1.必须对任何const或引用类型成员以及没有默认构造函数的类类型的任何成员使用初始化列表
       例:
class Test
{
private:
const int a;
int b;
 
public:
Test(int a);
}
 
Test::Test(int i)
{
 a=i; //错误,不能对常量赋值
 b=i; //正确
}
但我们可以通过初始化列表来完成给常量制定值:
Test::Test(int i):a(i),b(i){};

2.成员初始化的次序

    例:

class Test{
  int i;
  int j;
 public:
   Test(int a):j(a),i(j){};
}
    注意,构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。
              成员的初始化的次序就是定义成员的次序,第一个成员首页被初始化,然后是第二个,以此类推!所以,在这个构造函数中实际上是用尚未初始化的j值来初始化i,这里会给出一个警告!

3.初始化列表可以是任意表达式

例:Test::Test(int a,string b,double c):r1(a),r2(b),r3(a*c){};

4.在构造函数中用初始化列表去给成员变量赋值要比在构造函数体中赋值的效率要高

        为什么要说它效率高呢?在《C++ Primer》中写到:

从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。

     计算阶段由构造函数函数体中的所有语句组成。并且,不管成员变量是否在构造函数初始化列表中显式初始化,在执行构造函数之前,都要初始化成员变量。所以,在上面的实验例子中,首先会调用构造函数的初始化列表(先初始化),再去检查在构造函数的函数体内是否有其他赋值、计算之类的运算(再计算)。于是,我把第三个构造方法改为:

Ratio(int a,int b):num(a),den(b){
disp();
num =44;
den =55;
};
输出结果为:
4/9
1/2
3/2
44/55    
       可以看到,在执行构造函数的函数体时,num和den这两个成员变量是已经被赋值了的(当然,严格来讲这里是被初始化了),不过执行函数体之后它们的值都被覆盖了!
       不过他们的结果是一样的,而且在这种基本的数据类型上是看不到效率上的差异的,但是如果为复杂的数据类型,应该可以看到差异。书中的原话是:这个区别的重要性取决于数据成员的类型

在初始化列表中---实例举例子说明:

        编写一个有理函数Ratio,数据成员包括分母den,分子num,及一个disp()方法,以a/b的形式来表示有理数的形式。要求为该类写三个构造函数,分别满足以下几个条件:
1.使用初始化列表的默认构造函数;

2.使用初始化列表的带一个参数的构造函数;

3.使用初始化列表的带两个参数的构造函数

#include "stdafx.h"
#include "iostream"
using namespace std;
 
class Ratio{
private:
int num,den;
public:
    Ratio():num(1),den(2){};
    Ratio(int a):num(a),den(2){};
    Ratio(int a,int b):num(a),den(b){};
void disp();
};
void Ratio::disp()
{
  cout<<num<<'/'<<den<<endl;
}
int main(int argc, char* argv[])
{
Ratio r1,r2(3),r3(4,9);
r1.disp();
r2.disp();
r3.disp();
return 0;
}

输出结果:

1/2
3/2
4/9

原创粉丝点击