类的常成员分为常数据成员和常成员函数。“常”代表“只读”,也就是说一旦确立,一般情况下不会被改变。
常数据成员
常数据成员是只读变量,只能读取,不能修改。对于每个对象,常数据成员都是不可变的,但不同对象的常数据成员可以不同。在对其进行初始化的时候,要用到构造函数的初始化列表
,而不能像其他变量一样,直接在构造函数内初始化。初始化列表在构造函数的()和{}之间,格式为:变量名(值)
class Date{
private:
const int c;
int b;
public:
Date():c(5){//将c赋值为5
b=2;//普通变量的初始化
}
Date(int x):c(x){//用参数将c赋值为x
b=x;
}
};
int main()
{
Date d1,d2(6);
return 0;
}
可以发现,常数据成员的存在并没有影响对象的定义:
- 用无参构造函数定义对象d1,d1中b=2,c=5;
- 用有参构造函数定义d2,d2中b=c=6;
定义完成后,常成员c永远是这个值,不能再更改,而普通成员b可以随意更改。
若有多个常数据成员,在初始化的时候用,
隔开:
class Date{
private:
const int a,b,c;
public:
Date():a(5),b(2),c(1){}
Date(int x):a(x),b(2),c(x){}
};
可以看出,如果没有需要初始化的普通数据成员,也不能省略{}
注意:若一个变量同为“常数据成员”和“静态数据成员”,那么要按照静态数据成员的方式进行初始化:
class Date{
private:
static const int a;//static在前
};
const int Date::a=0;
常成员指针/引用
对于常成员指针、常成员引用,“初始化列表”中的()
可以替代=
的所有作用:
class Date{
private:
const int t,&m,*p;
public:
Date():t(2),m(t),p(&t){}
//如果是普通数据成员,相当于m=t,p=&t
void print(){
cout<<m<<" "<<*p;
}
};
int main( )
{
Date d;
d.print();
return 0;
}
输出:
2 2
常成员函数
一般情况下,常成员函数不能修改变量,只能读取变量。常成员函数只在声明/实现的时候添加const
符号,而调用的时候不再需要添加const符号。const符号添加在()和{}之间。
class Date{
private:
const int y,m;
public:
Date():y(2020),m(2){}//初始化
void print() const;//声明(外联函数)
};
void Date::print() const {//实现
cout<<y<<" "<<m;
}
int main( )
{
Date d;
d.print();//调用时没有添加const符号
return 0;
}
输出:
2020 2
ps.常成员函数也可以修改一种特殊类型的变量:mutable
型(与const型相反)
常对象
常对象不能调用普通成员函数,只能调用常成员函数。不过普通数据成员和常数据成员都可以被调用。
常对象定义时,类名
和const
位置随意。
class Date{
private:
const int y;
public:
Date():y(2020){}
void print() const{
cout<<y;
}//常成员函数
};
int main( )
{
const Date d1;
//const在前/在后都行
Date const d2;
d2.print();//常对象只能调用常成员函数
return 0;
}