線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1797
推到 Plurk!
推到 Facebook!

「C++」 operator overloading

尚未結案

中階會員


發表:36
回覆:142
積分:70
註冊:2003-07-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-11-29 23:29:33 IP:163.23.xxx.xxx 未訂閱
各位前輩: 小弟找了十幾本 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-11-30 11:28:01 IP:203.187.xxx.xxx 未訂閱
若 //-------------------------------------    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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-11-30 12:57:19 IP:163.23.xxx.xxx 未訂閱
tqpzxy 您好:    謝謝您的回應 : ) 如果是作業,那小弟唯一的選擇就很明確了 書中有提示大概可以怎麼做,不過小弟不解 有一段話寫著: >> . >> > > > >
tqpzxy
一般會員


發表:13
回覆:22
積分:7
註冊:2003-11-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-11-30 23:02:09 IP:203.187.xxx.xxx 未訂閱
流 您好:    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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-11-30 23:16:36 IP:203.187.xxx.xxx 未訂閱
忘了提一點... 您說: 那反之的意思應該是可以把 Phone 寫為 ostream 的 member 這句話是正確的 但是 通常 programer 不會想要更動 vender 提供的 library 因為那些 library 通常是由一些「權威人士」寫的 他們寫的 library 通常既安全且效率又高 若習慣把自己寫的函數隨意的加入 library 中 則可能會造成 library 亂成一團 未來想維護或更新版本就會比較麻煩 所以最好是把自己寫的 和 vender 提供的分開

中階會員


發表:36
回覆:142
積分:70
註冊:2003-07-24

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-11-30 23:32:13 IP:163.23.xxx.xxx 未訂閱
tqpzxy 您好:    看了您的回覆,小弟現在正在努力的嘗試 因為小弟看到您回覆: 其「物件」倒是可以成為另一類別的 member 所以小弟在 myclass 的宣告中加了 ostream t 沒有更動到原來的 library 雖然不確定這樣是不是對的,但 compile 是沒問題 除了在我的 constructor 要 initial member mycalss::t 請問前輩這個要怎麼處理? 小弟這晚會繼續試試你回覆的相關提示! 因為這是作業,所以不會去修改原來的 library 只是沒寫出來或什麼都不懂就放棄覺得很可惜 其他的題目一個禮拜前就已經寫好了 感情您的回應,獲益良多!

中階會員


發表:36
回覆:142
積分:70
註冊:2003-07-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-12-01 03:23:26 IP:163.23.xxx.xxx 未訂閱
各位前輩:    小弟試了一整晚還是沒能符合 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 # include # include # include class PhoneNumber { friend istream &operator >> ( istream& , PhoneNumber & ) ; friend ostream &operator << ( ostream& , const PhoneNumber & ) ; private: char areaCode[4] ; char exchange[4] ; char line[5] ; } ; ostream &operator<< ( ostream &output , const PhoneNumber &num ) { output << "(" << num.areaCode << ") " << num.exchange << "-" << num.line ; return output ; } istream &operator>> ( istream &input , PhoneNumber &num ) { input.ignore() ; input >> setw(4) >> num.areaCode ; input.ignore(2) ; input >> setw(4) >> num.exchange ; input.ignore(); input >> setw(5) >> num.line ; return input ; } void main() { PhoneNumber phone ; cout << "Enter phone number in the form (123) 456-7890\n\n" ; cout << "Enter your phone number : " ; cin >> phone ; cout << "The phone number entered was : " << phone << endl ; getch(); } 小弟能力有限,無法改成 member function 去 Access private 的內容 只可惜題目不能將 private 的內容改為 public,果真如此那小弟就會做 只要把 private 改成 public ,再將紅色的部份拿掉就可以 work 感謝
tqpzxy
一般會員


發表:13
回覆:22
積分:7
註冊:2003-11-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-12-01 10:18:44 IP:203.187.xxx.xxx 未訂閱
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 
class MyClass
{
public:
   std::ostream & operator << (std::ostream &);
   . . .
private:
   char areaCode[4] ;
   . . .
};
//------------------------------------------    // myclass.cpp -----------------------------
#include 
#include "myclass.h"    std::ostream & MyClass::operator << (std::ostream & os)
{
   os << areaCode;   // Or something like that
   return os;
}    . . .
//------------------------------------------    // main.cpp --------------------------------
#include "myclass.h"
. . .
int main()
{
   MyClass MyObj;
   . . .
   MyObj << std::cout; // Using memb. func. of MyObj to achieve output op.
   . . .
}
//------------------------------------------
發表人 - taishyang 於 2003/12/01 13:34:33

中階會員


發表:36
回覆:142
積分:70
註冊:2003-07-24

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-12-01 13:20:27 IP:163.23.xxx.xxx 未訂閱
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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-12-01 14:38:27 IP:203.187.xxx.xxx 未訂閱
流 您好:    首先必須強調我非相關科系出身 目前也不是從事程式相關 所以我的意見您應該「僅作參考」    回到正題    您要詢問的 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
系統時間:2024-05-18 16:13:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!