我们知道C++中const可以用于修饰普通变量、指针变量、引用变量、函数入参以及函数名,例如:
//常量const int nMaxNum = 5;//修饰引用const int& refInt = nMaxNum;//修改指针const int *p = &nMaxNum;class CTest{public: //修饰入参 void fun1(const int& a) { cout << "i am const reference param" << endl; } //修饰函数,常成员函数 virtual void print() const { cout <<"i am print" << endl; }}
以上const用法均是正常的,编译器没有报错,我的系统配置是VS2008+Win7系统。
当const遇上函数重载会是什么情况呢,下面一起见证奇迹!
const修饰函数入参
直接上代码,示例如下:
class CTest{public: //入参数是修饰引用 void Refernce(const int& a) { cout << "i am const reference param" << endl; } void Refernce(int& a) { cout << "i am reference param" << endl; } //入参数是修饰指针 void Ptr(const int* a) { cout << "i am const ptr param" << endl; } void Ptr(int* a) { cout << "i am ptr param" << endl; } //修饰变量,var不是函数重载,编译错误。 //“void CTest::Var(int)”: 已经定义或声明成员函数 void Var(int a) { cout << "i am int para" << endl; } void Var(const int a) { cout << "i am const int param" << endl; } //修饰变量名,编译报错 //void CTest::ConstPtr(int *const )”: 已经定义或声明成员函数 void ConstPtr(int * const a); void ConstPtr(int * a);};
测试代码&结果:
CTest test;const int a = 5;test.Refernce(a); //->Refernce(const int& a)int b = 6;test.Refernce(b); //->Refernce(int& a)const int c = 8; test.Ptr(&c); //->Ptr(const int* a)int d = 7; test.Ptr(&d); //->Ptr(int* a)test.Var(c); //var函数编译报错,void CTest::Var(int)”: 已经定义test.Var(d);
从以上几个例子可以发现:const修饰函数入参时,仅对指针和引用有效,其他类型是无效的。
const修饰函数名
在类中的函数是我们叫做类成员函数,若某个函数是类成员函数,则该函数可用const关键字去修饰,用const修饰的成员函数叫做常成员函数;该函数不允许对成员变量进行修改。例如:
class CBase{public: //修饰函数,常成员函数 virtual void print() const { cout <<"i am base" << endl; }};class CDeriver:public CBase{public: //普通成员函数 virtual void print() { cout <<"i am derive" << endl; }};
测试代码:
CBase* pBase = new CDeriver;pBase->print();delete pBase;pBase = NULL;
问:该测试代码输出结果是什么?
答:实际上输出结果是”i am base”若大家知道虚函数的知识点,第一反应则认为CDeriver重写了print函数,因此输出“i am derive”;
实际上CDeriver是在自己的范围内重新定义了一个同名函数,该函数不是常成员函数,并没有重写基类的print函数,因此pBase->print()调用的是基类中的print函数,证据如下:
总结
- 进行函数重载时,const关键字修饰的是引用参数或者指针参数,是有效的函数重载,否则编译器报错。
- 在成员函数中,有const关键字修饰的和无const关键字修饰的成员函数,实际上是两个不同的函数。