闲谈成员初始化列表

C++里有个所谓有initializer list,即成员初始化列表.以前对初始化列表了解甚少,

不知道何时应该用何时最好不用.那么现在就总结一点吧.

#include <iostream.h>

class Man
{
public :
 Man(int age):m_age(age){};
// Man(int age){m_age = age};

  virtual void print(){cout<<"Man's age is "<<m_age<<endl;}

protected:
// const int m_age;
 int &m_age;
};

class Boy: public Man
{
public :
 Boy(int age):Man(age){};
 void print(){cout<<"Boy's age is "<<m_age<<endl;}

};

int main()
{
 Man *pMan = new Man(22);
 pMan->print();
 return 0;
}


在Lippman的C++ Primer里说通过成员初始化列表,类数据成员可以被显式初始化.成

员初始化列表是由逗号分隔的成员,名字实参对.有几个问题要思考,其一,为什么要设

计初始化列表这一功能;其二,什么时候用初始化列表;仅以个人的浅薄闲聊几句而已.

初始化列表是在程序进入构造函数之前执行的,我们要区别出初始化与赋值的不同.
如下:
1)Man(int age):m_age(age){};  //初始化
2)Man(int age){m_age = age};  //赋值

Lippman说二者的区别的重要性取决于数据成员的类型.这里有两种情况:
1) 对于成员类对象
如:class Man
{
   Man(string name):m_name(name){}; 
 private:
    string m_name;
};
对于string 类的m_name,我们用成员初始化列表来实现其赋值过程而不在构造函数体

内写诸如m_name = name;的赋值语句.并非后者不行,但效率差别巨大.[c++ primer]
这或许是lippman说"没有清楚认识到这个区别是程序错误和低效的常见源泉."的原因

吧.

2)对于内置类型的数据成员
这里又可以分为两类.其一是必须被初始化的东西.(包括const常量和引用) 其二是除

此之外.
如:
class Man
{
public :
 Man(int age):m_age(age){};  //这里也体现了初始化与赋值的不同
// Man(int age){m_age = age}; //不能用赋值的办法

protected:
// const int m_age;  //这就是两个特例.
 int &m_age;
};
对于除此之外的其它内置类型,两种方法的结果和性能一样.不过据说用初始化表更受

欢迎.


使用初始化列表还存在一种隐含的错误.就是对初始化顺序的认识.
如:
class X{
public:
  X(int val):j(val),i(j){};

private:
  int i;
  int j;
};
以上的初始化就是错误的.因为初始化顺序由类声明的顺序决定的.所以上面应该是初

始化i后j.而i要用没被初始化的j来初始化,于是错误发生.一个办法是:把一个成员对

另一成员的初始化放在构造函数内.

参考: C++ Primer第三版 Lippman 等.

posted on 2007-10-01 01:05 zim.NET 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/zimmerman/archive/2007/10/01/912402.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值