※ 引述《putumaxally (putumaxally)》之銘言:
: 問題(Question):overload operator 不能使用 pointer 當參數嗎?
: 上週在 C 語言的課堂上被老師問 pointer 跟 reference 的差別,我在
: 網路上找資料的時候看到這段程式碼
: enum day
: {
: Sunday, Monday, Tuesday, Wednesday, Thursady, Friday, Saturday
: }x;
: day& operator++(day& d)
: {
: d = (day)(d + 1);
: return d;
: }
: 不可以改成 day* operator++(day* d) 的形式
: 只有當參數是 T, T& 才是 member operator 嗎,所以 T* 一定不會用在
: operator overloading 嗎?
: 還有上面的例子是 prefix 的,那如果想要 postfix 該怎麼做呢
: http://ppt.cc/Sa3Y 關於 pointer 跟 reference 的差別,我這樣描述對嗎?
其實上面這個不是 member operator...
member operator 是在 class 當中直接寫 operator xxx
例如
class BigNumber
{
// ...
public:
BigNumber& operator ++ (); // member operator prefix ++
BigNumber operator ++ (int); // member operator postfix ++
};
enum 由於無法宣告 member function 所以不會有 member operator
因此只能用這個樣子寫在外面
同樣不得不寫在外面的狀況是 operator 的左邊是 primitive type
或是 operator 的左邊那個 class 你動不到
例如我前面推文提到的 std::string 的例子
在 std::string 這個 class 裡有個 member operator == 是吃 const char * 的
概念上像是這樣:
class string
{
// ...
public:
bool operator == (const char *rhs) const;
};
這使得我們可以寫 someStringObject == "someCString"
它就會去呼叫這個 member operator
實際上它會視為 someStringObject.operator == ("someCString") 進行呼叫
但是 "someCString" == someStringObject 卻不一樣了
因為左邊是 primitive type 無法對它定義 member
所以只好寫一個在 string 外面的 operator 它會長成像這樣:
bool operator == (const char *lhs, const string &rhs);
這樣一來 "someCString" == someStringObject 這句話
就會被視為 operator == ("someCString", someObject) 來進行呼叫
enum 的狀況由於無法定義 member function 只好用寫在外面的那種方式來定義
另一種要寫在外面的狀況的例子像是
ostream& operator << (ostream& out, const BigNumber& num);
由於 std::ostream 我們動不到 所以只好寫一個在外面的 operator
這樣一來 cout << someBigNumber
就會當成 operator << (cout, someBigNumber) 而呼叫到這個函式
(寫在外面的 operator 其實還有一個 issue 是 namespace, 不過那跟本文就無關了)
---
至於 prefix postfix 的問題
在 member operator 的狀況是像上面我寫的 BigNumber 那樣子
同理可推, 寫在外面的也是以多一個 int 參數來表示
以 enum day 為例的話 postfix ++ 會寫成
day operator ++ (day& d, int);
這個 int 參數純粹只是用來解決 overload resolution 而已
實際上是不會用到的
(編譯器實際上會丟一個 0 進去那個參數 不過那不重要)
而通常 postfix ++ 是會回傳 value 而不是回傳 reference
主要是因為要達成 postfix ++ 的語意會需要一個暫時物件
而你不能回傳一個暫時物件的 reference
好在這種狀況大部份情形都能夠啟動 RVO 最佳化省去一次複製
因此這樣寫不會有什麼問題
---
關於你的整理, 只有一個地方是錯的
陣列不是「傳址」
而是一個陣列變數除了某些特別的狀況之外
都會 decay 成一個指向其第一元素的指標
(特別的狀況例如在 sizeof 裡面的時候)
也就是說 那個例子裡 ptr = s; 這一行的 s 會 decay 成 &s[0]
實際上它做的就是 ptr = &s[0];
這在這個變數傳進函式時也是一樣的
而 &s 雖然也會得到指向同一個位置的指標
但它的型態卻是不一樣的:
&s 的型態是 int(*)[5] -- 一個指向「長度為 5 的整數陣列」的指標
因此即使 &s 跟 &s[0] 指向的位置一模一樣 但 ptr = &s; 還是不合法
--
1985/01/12 三嶋鳴海 1989/02/22 優希堂悟 1990/02/22 冬川こころ 1993/07/05 小町
つぐみ 歡迎來到 1994/05/21 高江ミュウ 1997/03/24 守野いづみ 1997/03/24 伊野瀬
チサト 1998/06/18 守野くるみ 打越鋼太郎的 1999/10/19 楠田ゆに 2000/02/15 樋口遙
2002/12/17 八神ココ 2011/01/11 HAL18於朱倉岳墜機 ∞與∫的世界 2011/04/02 茜崎空
啟動 2012/05/21 第貮日蝕計畫預定 2017/05/01~07 LeMU崩壞 2019/04/01~07 某大學合宿
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.195.39.85
※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1400977800.A.C11.html