在程序設計中我們會經常調用函數,調用函數就會涉及參數的問題,那么在形參列表中const形參與非const形參對傳遞過來的實參有什么要求呢?
先來看一個簡單的例子:
- #include <iostream>
- #include <string>
- using namespace std;
- void print_str(const string s)
- {
- cout<<s<<endl;
- }
- int main()
- {
- print_str("hello world");
- return 0;
- }
毫無疑問,const實參傳遞給const形參,正確調用函數,如果你將第4行代碼中的const去掉,也能得到正確的結果。那么在去掉const的基礎上將形參變為引用形參,會出現什么樣的結果呢?看下面的代碼:
- #include <iostream>
- #include <string>
- using namespace std;
- void print_str( string & s)
- {
- cout<<s<<endl;
- }
- int main()
- {
- print_str("hello world");
- return 0;
- }
發現編譯不通過,如果在第4行的string前加上一個const,就會通過編譯。進一步研究我們會發現指針形參與引用形參會出現類似的情況。
普通形參加不加const限定符對實參沒有影響,引用形參和指針形參前面沒有const限定符時,實參必須是非const的,而前面有const限定符時對實參也沒有什么影響。
為什么會出現這種情況?
原因在於實參的傳遞方式不同,函數中的形參是普通形參的時,函數只是操縱的實參的副本,而無法去修改實參,實參會想,你形參反正改變不了我的值,那么你有沒有const還有什么意義嗎?引用形參和指針形參就下不同了,函數是對實參直接操縱,沒有const的形參時實參的值是可以改變的,這種情況下怎能用函數來操縱const實參呢。
我一直這樣記憶:“對於變量的約束,允許加強,當絕對不能削弱.....”
例如:實參是const,那么形參如果是非const意味着可以在函數體中改變形參的值,使約束削弱了所以不行。對於使用&,自然也是這個道理。同樣的,指針里面的const也是這個樣子的,如果讓非const指針指向了const對象的地址,那么必然是無法通過編譯的,因為如果這樣做了,意味着可以通過這個指針改變本該是const的值了,顯然是使約束削弱了