这是一篇以前找工作时的记录~
额,为了面试,还是要看c++基本语法,const关键字的确是个纠结的东西。
首先文章 http://www.cnblogs.com/wxxweb/archive/2011/05/25/2056169.html 中简单介绍了const重载问题,如下4个版本的涉及const关键字的函数就是可以重载的
class Clx
{
public :
// 版本 1
int increase(int &val);
// 版本 2
int increase(const int &val);
// 版本 4
int increase(const int &val) const;
// 版本 3
int increase(int &val) const;
};
而如下两个版本的就不能重载
//
// 版本 A
//
int increase(const int val)
{
return val + 1;
}
//
// 版本 B
//
int increase(int val)
{
return ++val;
}
为何如此纠结,文中说“这是历史遗留问题,为了跟 C 兼容”,“由于 C 中函数参数只有传值一种传递方式,因此 const 只是告诉编译器,形参在函数里面值是不可以被改变的。但是这已经跟实参没有任何关系了,传递进来的只不过是一个副本。与之不同的是 C++ 有引用,传引用会对实参造成影响。”
嗯基本就是这个意思吧,值传递的时候去搞const就没什么意义了,而引用传递的时候,函数里可以真实的修改实参的值,所以会涉及到const。
那么版本1和版本2的基本差别就是传入值的差别,版本1对传入值的类型要求更宽松。如果传入的是个const的引用,那么会调用const版本的,如果是非const的引用,那么优先调用非const版本的,如果没有非const版本的,也可以匹配const的那个。反过来如果是const的引用,不能匹配非const版本的,原因比较简单就是const版本的变量在函数中也不希望也不能被修改。
版本1和版本3的差别在哪里呢,看起来是函数定义的后面有个const关键字,通过c++primer中的介绍大致就是什么样的对象就用什么样的函数,也就是const对象调用的是const版本,非const对象调用非const版本。我写了一段代码来测试:
class Test{
public:
Test(int x = 1):a(0),t(x){}
const Test& out(string& a) const{cout<<"out const"<<endl;return *this;}
Test& out(string& a){cout<<"out nonconst"<<endl;return *this;}
public:
const int a;
int t;
};
void run(){
const Test c;
string s = "haha";
Test a;
c.out(s); //out const
((Test)c).out(s); //out nonconst
((Test *)&c)->out(s); //out nonconst
c.out(s).out(s); //out const out const
a.out(s); //out nonconst
((const Test)a).out(s); //out const
((const Test*)&a)->out(s); //out const
a.out(s).out(s); //out nonconst out nonconst
}
通过代码示例可以看出,通过const对一个对象进行类型转换来调用不同的重载函数