c++构造函数(初始化式)被忽略的东西

不管是在c++,还是c#,或是java中,当人们一提到构造函数是,马上就回有人回答,是用来初始化成员变量的,没错,但是殊不知,后面却隐含了很多东西。

首先:构造函数用初始化式与在函数里面直接初始化有什么不同。

我先简单说一下初始化式,可能有人已经忘了什么是构造函数的初始化式。其实初始化式就是一个以冒号开始,接着是一个以逗号分隔的数据成员列表,每个数据成员后面跟着一个放在圆括号里的初始化式。而初始化式只能在构造函数的定义中而不能再声明中指定。如:

class A{
  public int a,b;
 public string c;
  A(const string &s):a(3),b(4),c(s){ }
};
我们也可以由下面的方式进行成员变量的初始化:
class A{
  public int a,b;
  public string c;
  A(const string &s){ a = 3;b = 4;c = s}
};

那么上面两个有什么区别呢?
我们先说一下,构造函数的执行过程分为两个阶段:(1)初始化阶段;(2)普通计算阶段。
普通计算阶段是由构造函数的函数体内的语句来构成。
那么我们来分析一下第二种方式的初始化:
这个构造函数在给类A的成员变量赋值之前,第一步要进行初始化变量c。所以这个构造函数使用了内部隐式的string类的构造函数对c进行初始化。当我们执行到普通计算阶段时,又对c进行了赋值。
那么什么样的构造函数必须使用初始化式来对成员变量进行赋值呢?
我这里给出两种,一种是const,另一种是引用类型。
为什么呢?我们可以想一想const变量要求在声明的时候就进行初始化,而如果我们采用第二种方式的话,在构造函数的第二个阶段,又会对const变量赋一次值,而这又违反了const变量的性质。关于引用类型的探讨留给读者。


第二个问题:
初始化列表中的次序
我们一般可能会认为初始化列表的顺序就是初始化成员函数的顺序,其实不是这样。而应该是定义成员变量的顺序。

下面给一个例子:

class M{
  int i;
  int j;
  public:
  M(int val):j(val),i(j){}

};
这个例子看起来似乎是用val初始化j,然后用j再初始化i。
然而,i其实是被先初始化的,他用未被初始化的j来初始化。
第三个问题
先看下面的程序

class M{
public: string a;
 M():a(10,'a'){}

};
void main()
{
	char* c = new char[10];
	M m;

	strcpy(c,m.a.c_str());
	cout<<c;
}

这个程序中输出了10个a
其实在初始化式中,如果有其他类类型的变量,可以直接使用那个类的构造函数来对这个M类中的对象初始化。例子中就是用string类的构造函数来初始化的。
至于为什么用c_str()函数,可以看下面这篇文章。
http://blog.csdn.net/gaotengguojianhong/article/details/7037942

 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值