我们知道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关键字修饰的成员函数,实际上是两个不同的函数。