「C++」 operator overloading |
尚未結案
|
流
中階會員 發表:36 回覆:142 積分:70 註冊:2003-07-24 發送簡訊給我 |
各位前輩: 小弟找了十幾本 C 有介紹 operator overloading 的書
每一本書只要有介紹到關於 "<<" 這個 operator 都以 friend 來處理
如:friend ostream &operator<< ( ostream & ,const object & )
小弟的作業是把 operator<< 寫成 class 的 member function
為此小弟已經 try 了一星期,始終無法將它變成 member function
希望前輩為小弟解惑
|
tqpzxy
一般會員 發表:13 回覆:22 積分:7 註冊:2003-11-13 發送簡訊給我 |
若
//-------------------------------------
A a;
B b;
. . .
a << b;
//-------------------------------------
則
a << b 只有兩種可能: 1. Member function of type A
A::operator<<(B) 2. Global function
operator<<(A, B) 除非打算更動 class A
否則寫成 global function 是你唯一的選擇
|
流
中階會員 發表:36 回覆:142 積分:70 註冊:2003-07-24 發送簡訊給我 |
|
tqpzxy
一般會員 發表:13 回覆:22 積分:7 註冊:2003-11-13 發送簡訊給我 |
流 您好: ostream 是一個類別 class
類別當然是不能成為另一類別的 member funtion
不過其「物件」倒是可以成為另一類別的 member 至於那段英文 和之前的討論並無矛盾 以下小弟舉幾個簡單的例子
// Code ----------------------- aClass aObj; cout << aObj; //----------------------------- 於是如先前所提到的 cout << aObj; 在 compiler 看來 不是 cout.operator<<(aObj); // member function of cout 就是 operator(cout, aObj); // global function 沒有第三種可能 若如您舉的例子 // Code ----------------------- aClass aObj; aObj << cout; //----------------------------- 則 在 compiler 看來 aObj << cout; 不是 aObj.operator<<(cout); // member function of aObj 就是 operator(aObj, cout); // global function 沒有第三種可能 但如果上述兩者同時存在的話(即 mem. func. 和 glob. func. 同時存在) 那麼 compiler 可能會有 ambiguity 的錯誤訊息 我是說「可能」(不太記得了...) 實際情形要 run 一下 如果您要把 aObj << cout 寫成 member function of aObj 並且達到輸出的功能 那麼 // Code ----------------------------------------------------------- ostream & aClass::operator << (ostream & os) { ... // 一些輸出的操作 例如下行 os->rdbuf()->sputn(Cstr_, strlen(Cstr_)); // Cstr_ 為 aClass 的成員 return os; } //----------------------------------------------------------------- 但 一般而言很少這樣做 因為 << 這個符號通常是拿來當作輸出用 而 >> 通常拿來當輸入用 如果 aClass 存在如上述般的成員函數 則可以有以下的操作 // Code -------------------------------- aClass aObj; int x; double y; . . . aObj >> cout << x << y; //-------------------------------------- 在 compiler 看來 類似於(類似≠等同) // Code -------------------------------- aClass aObj; int x; double y; . . . ostream & os = aObj.operator>>(cout); // return type is 'ostream &' ostream & os = os.operator<<(x); ostream & os = os.operator<<(y); //-------------------------------------- 但不能有以下的操作 // Code -------------------------------- aClass aObj; int x; double y; . . . x >> aObj >> cout << y; //-------------------------------------- 在 compiler 看來 類似於 // Code -------------------------------- aClass aObj1, aObj2; int x; double y; . . . ???#1 = x.operator>>(aObj); // 此函數存在否? ???#2 = ???#1.operator>>(cout); // 此函數存在否? ???#3 = ???#2.operator<<(y); // 此函數存在否? //--------------------------------------當然上述那些有問題的成員函數(某未知型態的成員) 也可能是 global function 如果上述那些成員函數 或者 global function 有定義 那麼你當然可以這樣操作 說了這麼多 希望沒有讓您覺得更混亂 建議把上次給您的回應多看一次 那個東西才是重點 剩下的只是延伸 發表人 - taishyang 於 2003/11/30 23:16:42 |
tqpzxy
一般會員 發表:13 回覆:22 積分:7 註冊:2003-11-13 發送簡訊給我 |
忘了提一點... 您說:
那反之的意思應該是可以把 Phone 寫為 ostream 的 member 這句話是正確的
但是 通常 programer 不會想要更動 vender 提供的 library
因為那些 library 通常是由一些「權威人士」寫的 他們寫的 library 通常既安全且效率又高
若習慣把自己寫的函數隨意的加入 library 中
則可能會造成 library 亂成一團
未來想維護或更新版本就會比較麻煩 所以最好是把自己寫的
和 vender 提供的分開
|
流
中階會員 發表:36 回覆:142 積分:70 註冊:2003-07-24 發送簡訊給我 |
tqpzxy 您好: 看了您的回覆,小弟現在正在努力的嘗試
因為小弟看到您回覆:
其「物件」倒是可以成為另一類別的 member
所以小弟在 myclass 的宣告中加了 ostream t
沒有更動到原來的 library
雖然不確定這樣是不是對的,但 compile 是沒問題
除了在我的 constructor 要 initial member mycalss::t
請問前輩這個要怎麼處理? 小弟這晚會繼續試試你回覆的相關提示!
因為這是作業,所以不會去修改原來的 library
只是沒寫出來或什麼都不懂就放棄覺得很可惜
其他的題目一個禮拜前就已經寫好了 感情您的回應,獲益良多!
|
流
中階會員 發表:36 回覆:142 積分:70 註冊:2003-07-24 發送簡訊給我 |
各位前輩: 小弟試了一整晚還是沒能符合 compiler 的要求
小弟將程式碼列出,懇請前輩幫忙修改 < class="code"> /*
the program of Fig. 18.3 contains the comment
// Overloading stream-insertion operator
( cannot be a member funtion
if we would like to invoke it with cout << somePhoneNumber ; ) Actually , it cannot be a member function of class ostream ,
but it can be a member function of class PhoneNumber
if we were willing to invoke it in either of the following ways : somePhoneNumber.operator<<( cout ) ;
or
somePhoneNumber << cout ; rewrite the program of Fig. 18.3 with the overloaded
stream-insertion operator<< as a member function and try the two preceding statements
in the program to prove that they work .
*/ # include
|
tqpzxy
一般會員 發表:13 回覆:22 積分:7 註冊:2003-11-13 發送簡訊給我 |
code 裡頭的 comment 是出自書本的吧?
他是說的很正確 只是作法很怪異
我猜「怪異」可能只是為了教學
實際上很少有人會以 MyObj << cout 來作為輸出(因為箭頭的方向不合邏輯) 還有 我猜您大概誤會題意了(或者我誤會您的題問) 題目要求的方向是 MyObj << cout 不是 cout << MyObj 他說 cout << MyObj 「寫成 memb. func. of cout 」不可行 因為需要更動 STL 因此要求寫成 MyObj << cout 而 MyObj << cout 誠如先前所言 不是 MyObj.operator << (cout) 就是 operator << (MyObj, cout) (前者為 MyObj 的 memb. func. 後者為 glob. func. ) 題目要求寫成 MyObj 的 memb. func. 於是. . . // myclass.h ------------------------------- #include發表人 - taishyang 於 2003/12/01 13:34:33 |
流
中階會員 發表:36 回覆:142 積分:70 註冊:2003-07-24 發送簡訊給我 |
tqpzxy 您好: 嗯,code 上的 comment 是書本上的,小弟怕解釋不清楚所以將原文一字不漏的打上
應該小弟表達不好,才誤導了您,這是小弟第一次碰上作業的問題
小弟從題目化簡為最簡狀況去測試 ostream 是 member function
大約試了大概十幾種寫法
不是無法成為 member function 就是 compile 沒過
然而經前輩的指導,小弟一下子就改出來了 小弟有去看過 >> 就可以
因為小弟有改過 >::> 感到不懂,希望您可大略的講解 如果小弟提的問題不好回答
可以跟小弟講什麼 src="http://newzgc.com/luck/image017.GIF"> 發表人 - 流 於 2003/12/01 13:24:20 也感謝 taishyang 大大默默付出的修改,也謝謝您 發表人 - 流 於 2003/12/01 14:01:14
|
tqpzxy
一般會員 發表:13 回覆:22 積分:7 註冊:2003-11-13 發送簡訊給我 |
流 您好: 首先必須強調我非相關科系出身
目前也不是從事程式相關
所以我的意見您應該「僅作參考」 回到正題 您要詢問的 namespace 的概念
以下約略說明一下
namespace 的定義方式 // file1.cpp ------------------------------- namespace MyNamespace { void print(const double &) {. . .} int x; // x 是 global variable } // file2.cpp ------------------------------- namespace MyNamespace { double sqrt(int) {. . .} double y; // y 是 global variable SomeType obj; } //------------------------------------------ 注意:雖在不同檔,但因為 namespace 的 identifier 相同,所以仍是同一個 namespace 。 使用方式 // main.cpp -------------------------------- int main() { MyNamespace::x = 2; MyNamespace::y = MyNamespace::sqrt(MyNamespace::x); MyNamespace::print(MyNamespace::y); . . . } //------------------------------------------ 其中 :: 稱為 scope operator 至於是幹啥用的?我想字面上已經很清楚 通常語法為 A::B 其中 A 為 class 名稱或 namespace 名稱 在 A 為 class name 時 B 可為 subtype 、 (static) member function 或 (static) member object 在 B 為 namespace identifier 時 B 可為 function 或 object namespace 的好處: 減少 identifier 重複的機會 如物件(或函數) NS1::x 不同於 NS2::x 其中 NS1 及 NS2 是兩個不同的 namespace 而 x 是一個物件(或函數)的 identifier namespace 的缺點: 要打很多字 要省去這個缺陷有以下兩個方法: 1. using directive 2. using declaration // Using directive ------------------------------ int main() { using namespace MyNamespace; // 以下可省去打字的功夫 x = 2; // x 仍是 global variable y = sqrt(MyNamespace::x); // y 仍是 global variable print(y); . . . } //----------------------------------------------- // Using declaration ---------------------------- int main() { using MyNamespace::x; x = 2; // x 變成 local variable float x = 5.5; // Error! 因為不允許兩個同名的 local variables using namespace MyNamespace; y = sqrt(x); // y 仍是 global variable int y = 567; // OK. 但此 y 不同於上一行的 y print(y); // i.e. 'print(567);' NOT 'print(1.414);' // 因為 locale var. 蓋掉 global var. . . . } //-----------------------------------------------發表人 - taishyang 於 2003/12/01 14:46:28 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |