class A
{
private:
int m_data;
public:
int getData() const;// const成员函数,只读不修改数据成员
void setData(int data);/普通函数
};
const成员函数使用需注意:
A. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。
A a1;
const A a2=a1;
a1.setData(1);//正确
a1.getData();//正确
a2.setData(2);//错误,const对象不能访问非const成员函数
a2.getData();//正确
B. const成员函数不可以修改对象的数据,不管对象是否具有const性质。它在编译时,以是否修改成员数据为依据,进行检查。
C. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的。
(四)const与类的数据成员
上面介绍了const修饰类的成员函数,这里顺便提下const修饰类的数据成员。const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。
class A
{
public:
int m_data;
const int m_data=1; //编译错误,只有静态常量整型数据成员才可以在类中初始化
...
};
const数据成员的初始化只能在类的构造函数的初始化表中进行。
class A
{
public:
int m_data;
const int m_const;
A(int data=1,int initConst=0);
};
//构造函数中初始化表中初始化const数据成员
A::A(int data,int initConst):m_const(initConst)
{
m_data=data;
}
(五)const与函数重载
const(或volatile)修饰参数类型时,函数重载的辨析。
(1)当参数的类型以const或volatile修饰时,在识别函数声明是否相同时,并不考虑const或volatile修饰符,只看参数变量的类型。
//不构成重载
void fun(int a);//整型变量
void fun(const int a);//整型变量,只是该变量在函数体内是只读的
(2)以下两个函数声明构成重载,因为参数是不同的类型,前者指向整型的指针,后者是指向常整型的指针,是不同类型的指针。
void fun(int *a);// 整型指针
void fun(const int *a); //常整型指针
(3)以下两个函数声明不构成重载,两者均是指向整型的指针,只是后者用const修饰了指针,所以不构成重载。
void fun(int *a); // 整型指针
void fun(int *const a); 整型常指针
(4)这里顺便提下,对于成员函数和加了const修饰的成员函数,显然从语法上无法区分调用哪个,但可以编译运行,测试结果显示程序调用了没加const修饰的成员函数。
#include
using namespace std;
class A
{
public:
void fun() const;
void fun();
};
void A::fun() const
{
cout<<"const";
}
void A::fun()
{
cout<<"no const";
}
void main()
{
A a;
a.fun();//输出:no const
}
摘自 tht的专栏