标题:成员初始化方法


1.内建型别(如int/float/char等)在初始化列表与函数体内初始化无区别;非内建型别的初始化应该在初始化列表中实现;const 常量必须在初始化列表中实现。

 

class myclass

{

public:

  myclass(const string& initval, char *initptr);

  ...

private:

  string val;

  char *ptr;

};

 

在写myclass构造函数时,必须将参数值传给相应的数据成员,有如下两种方法来实现:

1)用成员初始化列表:

 

myclass::myclass(const string& initval, char *initptr )

: val(initval), ptr(initptr)         //初始化列表进行初始化

{

}

 

2)在构造函数体内赋值:

 

myclass::myclass(const string& initval, char *initptr)

{

     val = initval;

     ptr = initptr;

}

 

class myclass

{

public:

     myclass(const string& initval, char *initptr);

     ...

private:

     const string val;

     char * const ptr;

};

 

这个类的定义要求使用一个成员初始化列表,因为const成员只能被初始化,不能被赋值。对象的创建分为:第一,数据成员初始化;第二,执行被调用构造函数体内的动作。

对有基类的对象来说,基类的成员初始化和构造函数体的执行发生在派生类的成员初始化和构造函数体的执行之前。对myclass类来说,这意味着string对象val的构造函数总是在程序执行到myclass的构造函数体之前就已经被调用了。问题只在于:string的哪个构造函数会被调用?这取决于myclass类的成员初始化列表。如果没有为val指定初始化参数,string的缺省构造函数会被调用。当在myclass的构造函数里对val执行赋值时,会对val调用operator=函数。这样总共有两次对string的成员函数的调用:一次是缺省构造函数,另一次是赋值。相反,如果用一个成员初始化列表来指定val必须用initval来初始化,val就会通过拷贝构造函数以仅一个函数调用的代价被初始化。

 

myclass::myclass(const string &initval, char *initptr)

:val = initval, ptr = initptr    //const成员只能被初始化,非内建型别为了提高效率最好使                               //用初始化列表

{

}

 

2.成员初始化顺序应该与声明的顺序一致。

C++类成员变量可以在构造函数中通过成员列表的方式进行初始化,但实现初始化的顺序并不是按照其敲入的顺序进行的,而是按其在类中的声明顺序进行的。

例如:

 

class MyClass

{

public:

  MyClass();

 

private:

  int m_a;

  int m_b;

  int m_c;

};

 

MyClass::MyClass()

: m_c(0), m_b(0), m_a(0)

{

}

 

上述代码中构造函数初始化成员列表的顺序是:m_a(0), m_b(0), m_c(0),即与成员变量的声明顺序一致而非初始化列表中的顺序一致。

 

3.静态成员的初始化

C++类中的静态成员不能在类定义里边初始化,只能在类定义外初始化,并且初始化只能做一次。如果静态成员是私有成员,那么除此以后,将无法在类外使用这个私有静态数据成员,除非定义了一些函数来访问。例如:

 

class myclass

{

public:

     myclass();

private:

     static int x;

     static float y;

}

 

//仅在初始化的时候可以在类外访问这个两个私有成员

int myclass::x = 0;

float myclass::y = 1.1;



看文字不过瘾?点击我,进入周哥教IT视频教学
麦洛科菲长期致力于IT安全技术的推广与普及,我们更专业!我们的学员已经广泛就职于BAT360等各大IT互联网公司。详情请参考我们的 业界反馈 《周哥教IT.C语言深学活用》视频

我们的微信公众号,敬请关注