1 常数据成员只能通过构造函数初始化表对其进行初始化
常数据成员只能通过构造函数初始化表对其进行初始化,任何其它函数都不能对常数据成员赋值。如类体中定义了常数据成员hour:
constint hour;//定义hour为常数据成员;
不能采用在构造函数中对常数据成员赋值的方法,下面的用法是非法的:
Time::Time(inth)
{hour= h;} // 非法,不能对之赋值
因为常数据成员是不能被赋值的。
如果在类体外定义构造函数,应写成如下形式:
Time::Time(inth):hour(h){} //通过参数初始化表对常数据成员hour初始化
常对象的数据成员都是常数据成员,因此在定义常对象时,构造函数只能用参数初始化表对常数据成员进行初始化。【???注意:在实际中常对象的数据成员是可以通过函数体进行初始化的】
—《C++面向对象程序设计(第2版)》P91-P92
分析:构造函数可以分为两个阶段:(1)初始化阶段(利用初始化列表完成);(2){}函数体赋值阶段。
所以:(1)常数据成员只能通过构造函数的初始化表对其初始化;
(2)当数据成员是引用类型时,也只能使用构造函数的初始化表进行初始化。
2 如果数据成员是数组,则应当在构造函数的函数体中用语句对其赋值,而不是在参数初始化表中对其初始化
C++中可以再构造函数的函数体重通过赋值语句对数据成员实现初始化。同时还提供另一种初始化数据成员方法—参数初始化表来实现对数据成员的初始化。这种方法不再函数体内对数据成员初始化,而是在函数首部实现的。如
Box::Box(inth, int w, int len)//在类体外定义带参数的构造函数
{height= h;
width = w;
length =len;
}
可以改用以下形式:
Box:Box(int h, int w,int len):height(h),width(w),length(len){}
即在原来函数首部末尾加一个冒号,然后列出参数的初始化表。上面的初始化表示:用形参h的值初始化数据成员height,用形参w值初始化数据成员width,用形参len的值初始化数据成员length。后面的花括号是空的,即函数体是空的,没有任何执行语句。以上两种构造函数的作用是相同的。用参数初始化表发可以减少函数体的长度,使构造函数显得精炼简单,这样可以直接在类体重(而不是在类外)定义构造函数。
说明:如果数据成员是数组,则应当在构造函数的函数体中用语句对其赋值,而不是在参数初始化表中对其初始化。如:
Class Student
{public:
Student(int n,chars,nam[]):num(n),sex(s)
{strcpy(name,nam);}
private:
int num;
char sex;
char name[20];
};
—《C++面向对象程序设计(第2版)》P73-P74
3 静态数据成员不能用参数初始化表对静态数据成员初始化
(1) 如果声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中指定了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。
(2) 静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,至程序结束时才释放空间。
(3) 静态数据成员可以初始化,但只能在类体外进行初始化。
注意:静态数据成员不能用参数初始化表对其初始化。如在定义Box类中这样定义构造函数是错误的:Box(int h, int w, int len):height(h){}
(4) 静态数据成员可以通过对象名引用,也可以通过类名引用。
—《C++面向对象程序设计(第2版)》P104-P105
分析:静态数据成员可以初始化,但只能在类体外初始化,并且不能用参数初始化表对其初始化。
如: class Box
{
public:
int volume();
private:
static int height;
int width;
int length
};
int Box::height = 10; //正确
Box(inth, int w, int len):height(h){} //错误
静态成员与对象无关,属于整个类,构造函数是构造某个具体的对象。创建一个对象的时候会用到初始化表,但是静态成员在对象创建之前就已经存在了,所以不需要再初始化表中初始化。