const 对象的一般形式
● 类型名 const 对象名[(构造实参表列)];
● const 类型名 对象名[(构造实参表列)];
注意:常对象必须要有初值(因为以后不能改值了)。
限定作用
定义为const的对象的所有数据成员的值都不能被修改。
凡出现调用非const的成员函数,将出现编译错误。但构造函数除外。
1 2 3
| Time const t1(12,34,46); t1.set_Time(); t2.show_Time();
|
mutable
对数据成员声明为mutable(易变的)时,即使是const对象,仍然可以修改该数据成员值。
常对象成员
常数据成员
使用const说明的数据成员称为常数据成员,其值是不能改变的。
如果在一个类中说明了常数据成员,那么构造函数就只能通过初始化列表对该数据成员进行初始化,而任何其他函数都不能对该成员赋值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Time { const int hour; Time(int h):hour(h){} }; class Time { const int hour; Time(int h) { hour = h; } };
|
常数据成员举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <iostream.h> class Date { public: Date(int y,int m,int d); void showDate(); const int &r; private: const int year; const int month; const int day; }; Date::Date(int y,int m,int d):year(y),month(m),day(d),r(year){ } inline void Date::showDate() { cout<<"r="<<r<<endl; cout<<year<<"."<<month<<"."<<day<<endl; } int main() { Date date1(1998,4,28); date1.showDate(); return 0; }
|
常成员函数
在类中使用关键字const说明的函数为常成员函数。
常成员函数的说明格式如下:
类型说明符 函数名(参数表)const;
1 2 3 4 5
| void show_Time() const; void Time::show_Time const { cout << hour << minute << sec << endl; }
|
注意:const是函数类型的一个组成部分,在声明函数和定义函数时都要有const关键字,在调用时不必加const。
常引用作函数形参
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<iostream.h> int add(const int& i,const int& j); int main() { int a=20; int b=30; cout<<a<<"+"<<b<<"="<<add(a,b)<<endl; return 0; } int add(const int& i,const& j) { return i+j; }
|
如果将一个对象说明常对象,则通过该对象只能调用它的常成员函数,而不能调用普通成员函数。而且常成员函数也不能更新对象的数据成员。
常成员函数的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream.h> class Date { public: Date(int y,int m,int d); void showDate(); void showDate() const; private: int year; int month; int day; }; Date::Date(int y,int m,int d):year(y),month(m),day(d){ } void Date::showDate() { cout<<"ShowDate1:"<<endl; cout<<year<<"."<<month<<"."<<day<<endl; } void Date::showDate() const { cout<<"ShowDate2:"<<endl; cout<<year<<"."<<month<<"."<<day<<endl; } int main() { Date date1(1998,4,28); date1.showDate(); const Date date2(2002,11,14); date2.showDate(); return 0; }
|
常成员函数只能引用本类中的数据成员,而不能修改它们,即成员数据不能作为语句的左值。(注意:可以改mutable成员)
const对象及mutable成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Time { public: Time() { hour = 0; minute = 0; } void set_Hour(int h) const { hour = h;} void set_Minute(int m) { minute = m; } void show_Time() const { cout<<hour <<":"<<minute << endl; } private: mutable int hour; int minute; }; int main() { Time t1; t1.set_Hour(8); t1.set_Minute(8); t1.show_Time(); Time const t2; t2.set_Hour(8); t2.set_Minute(8); t2.show_Time(); return 0; }
|
常成员的使用
● 如果在一个类中,有些数据成员的值允许改变,另一些数据成员的值不允许改变,则可以将一部分数据成员声明为const,以保证其值不被改变,可以用非const的成员函数引用这些数据成员的值,并修改非const数据成员的值。
● 如果要求所有的数据成员的值都不允许改变,则可以将所有的数据成员声明为const,或将对象声明为const(常对象),然后用const成员函数引用数据成员,这样起到“双保险”的作用,切实保证了数据成员不被修改。
● 如果已定义了一个常对象,则只能调用其中的const成员函数,而不能调用非const成员函数(不论这些函数是否会修改对象中的数据)。如果需要访问对象中的数据成员,可将常对象中所有成员函数都声明为const成员函数,但应确保在函数中不修改对象中的数据成员。
指向常对象的指针变量
指向常对象的指针变量的一般形式
const 类型 ✱指针变量名
1 2 3
| const char *pc; *pa = 'a'; pa++;
|
1 2 3
| Time t1; const Time *pt; *pt = t1;
|
关于指向常对象的指针变量的说明
● 指向常对象(变量)的指针变量,不能通过它来改变所指向目标对象的值,但指针变量的值是可以改变的。
● 如果被声明为常对象(变量),只能用指向常对象(变量)的指针变量指向它,而不能非const型指针变量去指向它。
1 2 3
| const int a = 10, b = 20; const int *pa = &a; int *pb = &a;
|
● 指向常对象(变量)的指针变量除了可以指向常对象(变量)外,还可以指向未被声明为const的对象(变量)。此时不能通过此指针变量改变该变量的值。
● 指向常对象(变量)的指针变量可以指向const和非const型的对象(变量),而指向非const型变量的指针变量只能指向非const的对象(变量)。
1 2
| const int *pa = &b; int *pb = &a;
|
● 如果函数的形参是指向非const型变量的指针,实参只能用指向非const变量的指针,而不能用指向const变量的指针,这样,在执行函数的过程中可以改变形参指针变量所指向的变量(也就是实参指针所指向的变量)的值。
1 2 3 4 5
| void f(Time *pt); Time *p1; const Time*p2; f(p1); f(p2);
|
● 基本规则:希望在调用函数时对象的值不被修改,就应当把形参定义为指向常对象的指针变量,同时用对象的地址作实参(对象可以是const或非const型)。如果要求该对象不仅在调用函数过程中不被改变,而且要求它在程序执行过程中都不改变,则应把它定义为 const型
对象的常引用
在C++中,经常用常指针和常引用作函数参数。这样既能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝,可以提高程序运行效率。
对象的常引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Time { public: Time(int,int,int); int hour; int minute; int sec; }; Time::Time(int h,int m,int s) { hour = h; minute = m; sec = s; } void fun1(Time &t) { t.hour = 18; } void fun2(const Time &t) { t.hour = 18; int main() { void fun1(&); void fun2(const Time &); Time t1(10,13,56); fun(t1); cout<<t1.hour<<endl; return 0; }
|
非常对象和常对象的比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include<iostream.h> class Sample { public: int m; Sample(int i,int j){ m=i; n=j;} void setvalue(int i){ n=i; } void disply() { cout<<"m="<<m<<endl; cout<<"n="<<n<<endl; } private: int n; }; int main() { Sample a(10,20); a.setvalue(40); a.m=30; a.disply(); return 0; }
|
const型数据的小结
1 2 3
| const Time t = Time(1,2,3); const int a = 10; int const a = 10;
|
● t是常对象,其成员值在任何情况下都不能被改变。
● a 是常变量,其值不能被改变
fun 是Time类的常成员函数,可以调用该函数,但不能修改本类中的数据成员(非mutable)
1 2
| Time * const pt; int * const pa;
|
● pt 是指向Time对象的常指针
● pa 是指向整数的常指针。指针值不能改变
1 2
| const Time *pt; const int *pa;
|
● pt是指向Time类常对象的指针
● pa是指向常整数的指针,不能通过指针来改变指向的对象(值)