Re: [問題] overloading [] 疑問!!

看板C_and_CPP (C/C++)作者 (我要加入劍道社!)時間16年前 (2009/07/16 12:30), 編輯推噓4(402)
留言6則, 5人參與, 最新討論串2/3 (看更多)
我覺得你的問題在於你可能不太清楚 const member function 的意義。 所謂的 const member function 就是在宣告時於宣告式後加上 const: class Foo { public: void f(); // normal member function int g() const; // const member function private: int data; }; const member function 的意思是在這個 function 中,並不會去改變 物件中的 member variable(註)。因此若你宣告一個 const Foo 物件, 你不能呼叫 f(),因為 f() 的內部可能會改變 member variable,但 你可以呼叫 g()。 void Foo::f() { data = 10; // OK } int Foo::g() const { data = 10; // 錯誤,g() 是 const member function,不能修改 data return data; // 這行 OK,因為 return 並不會改變 data 的值 } void bar() { const Foo x; x.f(); // 錯誤,f() 可能會改變 x 的內容 x.g(); // OK,g() 不會改變 x 的內容 } 回到你的問題,為什麼你要同時提供 const 和 non-const operator[] 呢? 答案是你的物件可能同時在這兩種情況下用到: void baz(const Array& a) // a 是一個 Array 物件,我們不能改變它的內容 { cout << a[10]; // OK,因為我們沒有改變 a 的內容 a[10] = 5; // 這行會錯誤,因為我們不能修改 a 的內容 Array b = a; // 複製一份到 b,而且 b 不是 const 物件 b[10] = 5; // OK,我們可以改 b 的內容 } 我們不能單純提供 non-const operator[] 因為當 a 為 const 的時候,他無法呼叫 non-const operator[] class Array{ public: int& operator[](int index); // 沒有 const,寫 a[10] 會直接報錯 }; 但把它加上 const 就可以了嗎?當然不是: class Array{ public: int& operator[](int index) const; }; 若你這樣寫,那麼在 a[10] = 5 這行,compiler 會一聲不吭讓你編過, 於是使用者就發現他上當了:他明明說 a 是 const,但還是改變了 a 的內容! 於是你改成這樣: class Array{ public: const int& operator[](int index) const; // 或是另一個方式,兩者皆可行 // int operator[](int index) const; }; 這麼一來,cout << a[10] 可以編過,但 a[10] = 5 就會產生錯誤了。至於 non-const 物件 b,我們再額外提供 non-const operator[] // 最終版本 class Array{ public: const int& operator[](int index) const; // 給 a 用的 int& operator[](int index); // 給 b 用的 }; 所以你寫 a[10],會呼叫 const operator[];寫 b[10] 則是呼叫 non-const operator[]。讓對的寫法過關,不對的寫法產生 compiler error,這是設計 library 時一個重要的概念。 - 註:const member function 無法修改一般的 member variable,但若你在宣 告 member variable 時加上 mutable 關鍵字,就可以打破這項限制。因此, C++ 的 const member function 提供的是「邏輯上的常數性質」,亦即當 你呼叫 const member function 時,物件的內部資料可能還是有改變,只 是展現在外部的行為上是不變的。 題外話:看一個人懂不懂 C++,從 const 來看還滿準的。會用 const 的人, 多少都有一定的經驗。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 219.87.151.2 ※ 編輯: littleshan 來自: 219.87.151.2 (07/16 12:45)

07/16 13:15, , 1F
謝謝大大的解釋,關念清楚多了,另:我是新手,被大大說中
07/16 13:15, 1F

07/16 13:33, , 2F
會問「為什麼」,是好的開始,加油
07/16 13:33, 2F

07/16 14:08, , 3F
推 很清楚
07/16 14:08, 3F

07/17 01:43, , 4F
實作上補充,通常你可以只寫 const 版本的實作,然後
07/17 01:43, 4F

07/17 01:44, , 5F
non-const 去呼叫 const 版本,可以減少重複的程式碼
07/17 01:44, 5F

10/15 22:17, , 6F
來朝聖的... 好文 <(_ _)>
10/15 22:17, 6F
文章代碼(AID): #1ANgpdmL (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1ANgpdmL (C_and_CPP)