常对象:
可以在定义对象时加关键字const,指定对象为常对象,常对象必须要有初值,
如:Time const t1(12,34,46)//定义t1是常对象。这样该对象的t1中的所有数据成员都不能被修改。
定义常对象的一般形式为
类名 const 对象名[(实参表)] 也可以把const放在前面: const 类名 对象名[(实参表)] 二者等价。
在定义常对象时,必须同时对之初始化,不能再改变。
如果定义了一个常对象,只能调用其中的const成员函数,不能调用非const成员函数.常对象中的成员函数未加const声明,编译系统把它作为非const成员函数处理。
常对象的数据成员可以使用构造函数使用参数初始化表的方式进行初始化,也可以采用构造函数赋值的方式进行初始化。
常数据成员:
用关键字const来声明常数据成员,常数据成员的值是不能改变的,只能通过构造函数的参数初始化表来对常数据成员进行初始化,任何其他函数都不能对常数据成员赋值。如:const int hour;不能采用构造函数中对常据据成员赋初值的方法进行初始化,如:Time:Time(int h)
{hout = h;} //因为常数据成员是不能被赋值的。
常成员函数:
成员函数被const修饰,则本类中的成员变量不能被本类中的成员函数修改。(常成员函数可以访问常对象的数据成员,但不允许修改常对象的数据成员的值。)比如:void get _time() const;//将函数声明为const
const是常成员函数类型的一部分,在声明函数和定义函数时候都要有const关键字,在调用时候不加const。
常成员函数可以引用const数据成员,也可以引用非const的数据成员。const数据成员还可以被非const的成员函数引用。
常成员函数也不能调用另一个非const成员函数。
从以上可知常对象中,不能调用常对象的普通成员函数和常成员函数修改对象的数据成员。若一定要修改常对象的某个数据成员的值,对此对该数据成员声明为mutable 如:mutable int count;
把count声明为可变的数据成员,这样就可以用常函数来修改它的值
若对象被声明为常对象,则通过该对象只能调用它的常成员函数,而不能调用该对象的普通成员函数,(除了系统自动调用的隐式构造函数和析构函数)。常成员函数是常对象的唯一的对外接口。
若想要去引用常对象的数据成员,只需将该成员函数声明为const
如果必须要修改常对象中的数据成员的值,则必须将该数据成员声明为 mutable,
如:mutable int count 或者 int mutable count;两者都可以。
#include<iostream>
using namespace std;
#define TEST_01
#ifdef TEST_01
class volume
{
private://要修改常对象的成员则必须加入mutable 关键字
double length;
mutable double width;
double height;
public:
//double mutable width;
//volume(double h, double w, double l)
// :height(h), width(w), length(l)//常数据成员只能通过构造函数的参数初始化表对常数据成员进行初始化
//{
// /*
// height = h;
// width = w;
// length = l;
// */
//}
volume(double h, double w, double l)
{
height = h;
width = w;
length = l;
}
double Vol()
{
return height*width*length;
}
double peri()
{
return(4 * (height + width + length));
}
//在常对象中,若常函数想修改某个数据成员的值,则在定义前面加上mutable 关键字。
void SetValue(int ht)const //常函数不能修改常数据成员,也不能修改非const数据成员。
//除非是该数据成员加入mutable 关键字
{
// height = ht;
width = ht;
}
void display()const;
};
void volume::display()const
{
cout << "height:" << height << endl;
cout << "width:" << width << endl;
cout << "length:" << length << endl;
}
int main()
{
const volume t1(12,45,36);
t1.display();//常对象只能调用常成员函数,常对象的对外接口是常成员函数
//const volume t1(12, 45, 36);
t1.SetValue(13);//常成员函数只能调用常成员函数,不能调用非const成员函数
t1.display();
return 0;
}
代码中定义了常对象t1,定义了常成员函数display()和Setvalue(),因为常对象只能调用常成员函数。其中数据成员中对width添加了关键字mutable,常成员函数本身是不能修改数据成员的值,只能进行引用,而添加了mutable关键字,把width声明为可变的数据成员,这样就可以通过常成员函数改变它的值。
关于数据成员的引用:如下
数据成员 | 非const的普通成员函数 | const成员函数 |
非const的普通成员 | 可以引用,也可以改变值 | 可以引用,不可以改变值 |
const的数据成员 | 可以引用,但不可以改变值 | 可以引用,不可以改变值 |
const对象 | 不允许 | 可以引用,但不可以改变值 |
指向对象的常指针:
将指针变量声明为const型,这样指针变量始终保持为初值,不能改变,即其指向不变。
一般形式为:类名 *const 指针变量名
如:Time t1(10,12,15);
Time *const Pt1 = &t1;
指向对象的常指针变量的值不能改变,也就是说 Pt1永远只能指向t1,始终指向同一个值,但可以改变其所指向的对象的值。如改变t1的值。
//指向对象的常指针
//常指针是指该指针指向对象的地址变量不能变,即始终指向同一个对象,但是可以改变该对象中对应的值。
class volume
{
private:
double height;
double width;
double length;
public:
int re = 0;
volume(double h, double w, double l);
double Vol();
double peri();
void display()const;
void SetValue(double, double, double);
};
volume::volume(double h, double w, double l)
:height(h), width(w), length(l)
{}
double volume::Vol()
{
return height*width*length;
}
void volume::SetValue(double t1, double t2, double t3)
{
height = t1;
width = t2;
length = t3;
}
double volume::peri()
{
return(4 * (height + width + length));
}
void volume::display()const
{
cout << "height:" << height << endl;
cout << "width:" << width << endl;
cout << "length:" << length << endl;
}
int main()
{
volume x(10,11,12);
//volume *p = &x;//可以正常执行
//p->display();
cout << "******************************************************************" << endl;
volume *const pt = &x;
volume y(23, 43, 34);
pt->display();
//pt = &y;//此时出现错误,指向对象的常指针变量的值不能变,也就是说始终指向一个同一个对象,
//如程序中始终pt =&x;但是可以改变其所指向的值,也就是可以改变x中的值。
//即如下:
x = y;
cout << "x(即就是y)对象的值打印出来:" << endl;
x.display();
cout << "对象常指针指向x的值打印出来:" << endl;
pt->display();
return 0;
}
代码中定义了一个指向对象的常指针pt,并指向了对象t1,通过修改t1的值,可以随着改变值,但通过定义了一个新对象,pt重新指向报错,因为指向对象的常指针已经确定了指向对象的地址,则始终为该对象,不能再指向别的对象,否则会出错。
指向常对象的指针的介绍将在下节介绍。