這是一篇以前找工作時的記錄~
額,爲了面試,還是要看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對一個對象進行類型轉換來調用不同的重載函數