概述
C/C++用关键字const来定义常量,常对象和常成员概念的建立,明确规定了程序中各种对象的变与不变的界线,从而进一步增强了C++程序的安全性和可控性。 本文总结一下常对象、常数据成员、常成员函数的概念和特性。
常对象
在程序中,我们有时候不允许修改某些特定的对象。如果某个对象不允许被修改,则该对象称为常对象。C++编译器对常对象(const对象)的使用是极为苛刻的:
- const 对象不能被赋值,所以必须在定义时由构造函数初始化。
- const 对象不能访问非常成员函数,只能访问常成员函数。常成员函数是常对象唯一的对外接口方式 。
常对象定义格式如下: 类型 const 对象名; 或 const 类型 对象名;
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
36
#include <iostream>
using namespace std;
class Clock
{
private:
int H,M,S;
public:
Clock(int H=0,int M=0,int S=0)
{
this->H=H, this->M=M, this->S=S;
}
void ShowTime()
{
cout<<H<<":"<<M<<":"<<S<<endl;
}
void SetTime(int H=0,int M=0,int S=0)
{
this->H=H, this->M=M, this->S=S;
}
};
int main( )
{
const Clock C1(9,9,9); //定义常对象C1
Clock const C2(10,10,10); //定义常对象C2
Clock C3(11,11,11);
// C1=C3; //错误!C1为常对象, 不能被赋值
// C1.ShowTime(); //错误!C1为常对象, 不能访问非常成员函数
// C1.SetTime(0,0,0); //错误!C1为常对象,不能被更新!
C3. ShowTime();
return 0;
}
/****************运行结果****************/
11:11:11
常数据成员
使用 const 说明的数据成员称为常数据成员。常数据成员的定义与一般常变量的定义方式相同,只是它的定义必须出现在类体中。常数据成员使用时应注意:
- 常数据成员必须进行初始化,并且不能被修改。
- 常数据成员的初始化只能通过构造函数的初始化列表进行。
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
#include<iostream>
using namespace std;
class A
{
private:
const int& r; //常引用数据成员
const int a; //常数据成员
static const int b; //静态常数据成员
public:
A(int i):a(i),r(a) //常数据成员只能通过初始化列表来获得初值
{
cout<<"constructor!"<<endl;
}
void display()
{
cout<<a<<","<<b<<","<<r<<endl;
}
};
const int A::b=3; //静态常数据成员在类外说明和初始化
int main()
{
A a1(1);
a1.display();
A a2(2);
a2.display();
return 0;
}
/****************运行结果****************/
constructor!
1,3,1
constructor!
2,3,2
常成员函数
在定义时使用const关键字修饰的用于访问类的常对象的函数, 称为常成员函数。常成员函数的说明格式如下:返回类型 成员函数名 (参数表) const; 在定义与使用常成员函数时要注意:
- 常成员函数不能修改对象的数据成员,也不能调用该类中没有用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
31
class Date
{
private:
int Y, M, D;
public:
int year() const;
int month() const;
int day() const {return D;};
int day() {return D++;}
int AddYear(int i) {return Y+i;};
};
int Date::month() //错误,常成员函数实现不能缺少const
{
return M;
}
int Date::year()const
{
// return Y++; //错误,常成员函数不能更新类的数据成员
return Y;
}
Date const d1;
// int j = d1.AddYear(10); //错误,常对象不能调用非常成员函数
int j = d1.year(); //正确,常对象可以调用常成员函数
Date d2;
int i = d2.year(); //正确,非常对象可以调用常成员函数
d2.day(); //正确,非常对象可以调用非常成员函数