构造函数后加冒号是初始化表达式:
有四种情况下应该使用初始化表达式来初始化成员:
1:初始化const成员
2:初始化引用成员
3:当调用基类的构造函数,而它拥有一组参数时
4:当调用成员类的构造函数,而它拥有一组参数时。
在程序中定义变量并初始化的机制中,有两种形式,一个是我们传统的初始化的形式,即赋值运算符赋值,还有一种是括号赋值,如:
int a=10;
char b='r';//赋值运算符赋值
int a(10);/
char b('r');//括号赋值
以上定义并初始化的形式是正确的,可以通过编译,但括号赋值只能在变量定义并初始化中,不能用在变量定义后再赋值,冒号初始化是给数据成员分配内存空间时就进行初始化,就是说分配一个数据成员只要冒号后有此数据成员的赋值表达式(此表达式必须是括号赋值表达式),那么分配了内存空间后在进入函数体之前给数据成员赋值,就是说初始化这个数据成员此时函数体还未执行。 对于在函数中初始化,是在所有的数据成员被分配内存空间后才进行的。这样是有好处的,有的数据成员需要在构造函数调入之后函数体执行之前就进行初始化如引用数据成员,常量数据成员和对象数据成员。
class student
{
public:
student (int i,int j);
protected:
const int a;
int &b;
};
student ::student (int i,int j)
{
a=i;
b=j;
}
在Student类中有两个数据成员,一个是常量数据成员,一个是引用数据成员,并且在构造函数中初始化了这两个数据成员,但是这并不能通过编译,因为常量初始化时必须赋值,它的值是不能再改变的,与常量一样引用初始化也需要赋值,定义了引用后,它就和引用的目标维系在了一起,也是不能再被赋值的。所以C ++":"后初始化的机制,使引用和常量数据成员变为可能的,Student类的构造函数应为:
student ::student(int i,int j):a(i),b(j)
{
}
再比如这个例子:
#include "stdafx.h"
#include<iostream>
using namespace std;
class A
{
public:
int x;
A(int a=0)
{
cout<<"A Constructed\n";
x=a;
}
~A()
{
cout<<"A dis Constructed\n";
}
};
class B1:public A
{
public:
int y1;
B1(int test1=0,int test2=0)/*:A(b)*/ //就是这句
{
cout<<"B Constructed\n";
int testtt = 10;
A(testtt);
y1=test1;
}
~B1()
{
cout<<"B dis Constructed\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B1 b;
return 0;
}
这个列子就会出现编译错误,错误如下: 原因是实例化子类时候先调用父类构造函数再调用子类构造函数,如果在子类构造函数里面初始化父类会导致父类构造函数被调用两次。 请问那句后面的 :A(b) 代表什么啊,为什么要跟个B1基类的构造函数? 答:A(b)实际上是做的是用b初始化A的成员x;既x=b; :是初始化列表方式,具体见