虛擬 assignment operator |
|
jackyung
一般會員 發表:22 回覆:46 積分:13 註冊:2004-01-24 發送簡訊給我 |
以下是標準 assignment operator 的做法,延伸類別的 assignment operator 來源參數是延伸類別本身。 class A { public: A &operator=(const A &S) { ..... return *this; } }; class B:public A { public: B &operator=(const B &S) // 延伸類別的 assignment operator { A::operator=(S); ..... return *this; } }; 這樣的做法有個很大的問題: B b1; B b2; A a1; A *b1p = &b1; // b1 變裝為 A 的介面 *b1p = a2; // A 類別的部份的資料被複製了,但 B 類別的資料仍保持原狀沒變 A *b2p = &b2; *b1p = b2p; // A 類別的部份的資料被複製了,但 B 類別的資料並沒被複製 上面的做法只適用複製類別本身的資料,對於須保持資料一致性(上半身和下半 身須同一個人的)的物件將會有很大的問題,解決的辦法就是把 assignment operator 定義為 virtual,且延伸類別須覆載它: class A { public: virtual A &operator=(const A &S) // 虛擬的 assignment operator { ..... return *this; } }; class B:public A { public: virtual B &operator=(const A &S) // 覆載父類別的 assignment operator,參數為父類別 { A::operator=(S); ..... return *this; } virtual B &operator=(const B &S) // 延伸類別的 assignment operator 也定義成虛擬 { A::operator=(S); ..... return *this; } }; 但這麼做會變成另一個問題: *b1p = a1; // 這要怎麼辦 當 B 類別的 assignment operator 收到這樣的物件參數,要不就拒絕複製, 或者只複製 A 類別的資料,所以若把 assignment operator 定義為 virtual 要有個自覺--能不能複製成功由延伸類別決定,要使用有這種 virtual assignment operator 的類別做複製要有可能成功或不成功的心理準備。 還有另一個麻煩,若決定要使用 virtual assignment operator,那麼孫類別 是不是要覆載父類別和爺爺類別?有一個技巧可以解決這個麻煩: class B:public A { public: virtual B &operator=(const A &S) // 覆載父類別的 assignment operator,參數為父類別 { B *Src = dynamic_cast(&S); if(Src != NULL) *this = *Src; // 改叫 class B 的 assignment operator 來處理,也可能是叫到孫類別... else A::operator=(S); // 只複製父類別,若不想複製就刪掉這行 return *this; } virtual B &operator=(const B &S) // 延伸類別的 assignment operator 也定義成虛擬 { A::operator=(S); ..... return *this; } }; 這樣就只要覆載父類別的 assignment operator 就行了。發表人 - jackyung 於 2005/07/20 21:43:17 |
justdo
高階會員 發表:2 回覆:359 積分:222 註冊:2004-08-17 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |