关于构造方法的一个有趣的问题:初始化队伍

下面这段代码是有问题的,问题当然是关于构造方法:

   1: class A
   2: {
   3: private:
   4:     int i;
   5:     int j;
   6: public:
   7:     A ( int val )
   8:         :j ( val ), i ( j ) 
   9:     {}
  10:  
  11:     void print(){
  12:         cout<<i<<" "<<j<<endl;
  13:     }
  14: };
  15:  
  16: int main()
  17: {
  18:     A a(1);
  19:     a.print();
  20:     return 0;
  21: }

构造方法的实现很简单:先将val的值赋给j,再将j赋值给i。

但事实上并没有达到这个效果。

这里有一个初始化队伍的问题。初始化队伍这里指的就是构造方法中冒号后面的部分。

编译器在处理初始化队伍时,会根据成员变量的声明次序重新排序。也就是说,虽然构造方法是先对j进行初始化,但是,根据i和j的声明次序,实际上是先对i初始化,然后再对j进行初始化。这样一来,由于j还未初始化,所以最终的结果是i的值并不是val。下面是我在visual studio 2010下输出的结果:

-858993460 1

这种问题是很难发现的,要修正很简单,只需要将构造方法写为:

   1: A ( int val )
   2:     :j ( val )
   3: {
   4:     i = j;
   5: }

这里,还存在另一个知识点:执行初始化队伍( j(val) )在执行任何显式代码(explicit user code)之前,这里指的就是“i=j”。所以,就是先令j=val,然后令i=j。

输出的结果自然就是:

1 1

所以建议,如果是用一个数据成员对另一个数据成员进行初始化,即赋值,最好是把这样的代码写在构造函数体内(显式代码)。

参考文献:《深度探索C++对象模型》

转载于:https://www.cnblogs.com/AnnieKim/archive/2011/05/22/2053581.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值