您好,登錄后才能下訂單哦!
本篇內容介紹了“C++成員函數中const如何使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
首先我們要明白在C++中調用函數時存在兩種方法,即傳遞值和傳遞引用。
值傳遞時,調用函數時會創建入參的拷貝,函數中的操作不會對原值進行修改,因此這種方式中不需要使用 const 來修飾入參,因為其只是對拷貝的臨時對象進行操作。
傳遞地址時函數中的操作實際上是直接對原來的值進行修改,因此我們這里可以使用 const 修飾入參。
當const修飾函數入參時表示該參數不能被修改,這個是最好理解的,比如一個函數的功能是拷貝,那么入參中的源文件都會用 const 修飾。
void A::show(const int *b) { cout << "show const"; // error: read-only variable is not assignable // *b = 2; cout << b << endl; }
接下來我們要關注的是這里 const 對于函數重載的作用,這里給出結論,歡迎大家討論,對應按值傳遞的函數來說 const 不會有重載的效果,但是傳遞指針和引用是會有重載的效果。
void A::show(const int b) // void A::show(int b) // error class member cannot be redeclared void display(int *num); // overload void display(const int *num); // overload void fun(A &a); // overload void fun(const A &a); // overload
函數重載的關鍵是函數的參數列表——即函數特征標(function signature)。如果兩個函數的參數數目和類型相同,并且參數的排列順序也相同,則他們的特征標相同,而變量名是無關緊要的。
總結一下注意點:
如果輸入參數采用“值傳遞”,**由于函數將自動產生臨時變量用于復制該參數,該輸入參數本來就無需保護,所以不要加 const 修飾。**例如不要將函數 void Func1(int x)
寫成 void Func1(const int x)
。
如果參數作為輸出參數,不論它是什么數據類型,也不論它采用“指針傳遞”還是“引用傳遞”,都不能加 const 修飾,否則該參數將失去輸出功能(因為有 const 修飾之后,不能改變他的值)。
如果參數作為輸入參數,可以防止數據被改變,起到保護作用,增加程序的健壯性,建議是能加const盡量加上
上述測試代碼如下:
#include <iostream> using namespace std; class A { private: int a; public: A(int a) { this->a = a; } void show(int b); // error redeclared // void show(const int b); void display(int *num); // ok void display(const int *num); // ok void fun(A &a); void fun(const A &a); void happy(int * h); void hour(const int * h); }; void A::show(int b) { cout << "show: " << b << endl; } void A::display(int *num) { cout << "display:" << *num << endl; } void A::display(const int *num) { cout << "const display:" << *num << endl; } void A::fun(A &obj) { cout << "fun: " << obj.a << endl; } void A::fun(const A &obj) { cout << "const fun: " << obj.a << endl; } void A::happy(int *h) { cout << "happy:" << *h << endl; } void A::hour(const int *h) { cout << "const hour:" << *h << endl; } int main() { A a(1); const A a2(11); int b1 = 2; const int b2 = 3; // test overload a.show(b1); a.show(b2); a.display(&b1); a.display(&b2); a.fun(a); a.fun(a2); // test const a.happy(&b1); // a.happy(&b2); // error cannot initialize a parameter of type 'int *' with an rvalue of type 'const int *' a.hour(&b1); a.hour(&b2); return 0; } // ouptut show: 2 show: 3 display:2 const display:3 fun: 1 const fun: 11 happy:2 const hour:2 const hour:3
const 修飾返回值時,表示返回值不能被修改。需要注意的是如果函數返回值采用“值傳遞方式”,由于函數會把返回值復制到外部臨時的存儲單元中,加 const 修飾沒有任何價值。如果返回的是引用或指針,表示不能修改指向的數據。
一般用得多的是返回值是引用的函數, 可以肯定的是這個引用必然不是臨時對象的引用, 因此一定是成員變量或者是函數參數, 所以在返回的時候為了避免其成為左值被修改,就需要加上const關鍵字來修飾。
我們可以看如下代碼示例:
#include <iostream> using namespace std; class Alice { private: int a; public: Alice(int a): a(a) {} int get_a() {return a;} const int* get_const_ptr() {return &a;} int* get_ptr() {return &a;} }; int main() { Alice alice(1); int a1 = alice.get_a(); // ok cout << a1 << endl; const int a2 = alice.get_a(); // ok cout << a2 << endl; // error cannot initialize a variable of type 'int *' with an rvalue of type 'const int *' // int* b1 = alice.get_const_ptr(); const int* b2 = alice.get_const_ptr(); // ok cout << *b2 << endl; // ok // *b2 = 3; // error read-only variable is not assignable *(alice.get_ptr()) = 3; cout << alice.get_a() << endl; // 3 return 0; }
const 也可以用來放在函數末尾,用來修飾成員函數,表明其是一個常成員函數,這個對于初次接觸C++的同學來說會有點陌生,不過這也是C++中嚴謹的地方。先看代碼示例,學習任何編程技術都一定要寫對應的代碼,把它跑起來并分析結果才算是真正學會了,不會你只是知道了這個知識點,只知其然而不知其所以然。紙上得來終覺淺,絕知此事要躬行,這里的要躬行指的就是寫代碼。
首先來看如下的代碼
class Alice { private: int a; public: Alice(int a): a(a) {} void show(); }; void Alice::show() { cout << "hello Alice" << endl; } int main() { const Alice a(1); // error: 'this' argument to member function 'show' has type 'const Alice', but function is not marked const // a.show(); return 0; }
上述代碼會報錯,因為 show()
方法不是常成員函數,而 a 是常對象。本質上,成員函數中都有一個隱含的入參 this
, 這個 this
指的就是調用該方法的對象,而如果在函數的后面加上 const
,那么這個 const 實際上修飾的就是這個 this
。也就是說函數后加上了 const,表明這個函數不會改變調用者對象。
這里借用侯捷老師的圖片
上面圖片表明,在正常情況下:
non-const對象可以調用const 或者 non-const 成員函數
const 對象 只可以調用 const 成員函數
補充一點,**如果成員函數同時具有 const 和 non-const 兩個版本的話, const 對象只能調用const成員函數, non-const 對象只能調用 non-const 成員函數。**如以下代碼示例
#include <iostream> using namespace std; class R { public: R(int r1, int r2) { a = r1; b = r2; } void print(); void print() const; private: int a; int b; }; void R::print() { cout << "normal print" << endl; cout << a << ", " << b << endl; } void R::print() const { cout << "const print" << endl; cout << a << ", " << b << endl; } int main() { R a(5, 3); a.print(); const R b(6 ,6); b.print(); return 0; } // output normal print 5, 3 const print 6, 6
這里也是建議能加 const 的時候就加。
“C++成員函數中const如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。