您的位置:首页 > 编程语言 > C语言/C++

(原創) 若class中data member的container,含的是polymorphism的pointer,該如何big three? (C/C++)

2007-05-21 22:09 501 查看
Abstract
C++中一旦用到pointer,就得自己管理memory,若功力不夠,不是當機就是memory leak,所以能避免就避免,不過若要在container中放polymorphism object,就只能使用pointer,此時該如何big three呢?

Introduction
(原創) 若class中的data member有container,而且內含pointer時,也一定要big three!!(C++) 中已經討論了container中放pointer中該如何處理,但別忘了我們為什麼會在container中放pointer呢?就是為了polymorphism,所以一定會遇到一個inheritance hierarchy,而非之前討論的只有一層class。

我們知道處理big three中,主要就是要在copy constructor和assignment operator中重新new過,而非只是copy pointer,但因為container中放的是polymorphism object,我該怎麼針對適當的type去new呢?

我的第一個想法,就是用RTTI去判斷該polymorphism object的type為何,然後去new。

1#include <iostream>
2#include <vector>
3#include <algorithm>
4#include <functional>
5
6using namespace std;
7
8
18
34
43
52
95Base's print:1
Derived1's print:2
Derived2's print:3
Base's print:1
Derived1's print:2
Derived2's print:3

執行結果如預期,但copy contructor和assignment operator非常的醜

由於使用了RTTI,須不斷的去判斷type,這種寫法明顯的違反了OCP,若有新的type,就得改copy constructor和assignment operator的判斷式,算是很差的寫法。

再苦思許久之後,大陸的袁老弟給我一個建議,使用clone(),在Modern C++ Design 8.7節有個範例就是用這種方式,我試了之後,結果非常令我滿意。

Sample Code

1#include <iostream>
10#include <vector>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16
26
46
59
72
102Base's print:1
Derived1's print:2
Derived2's print:3
Base's print:1
Derived1's print:2
Derived2's print:3

37行

copy constructor就變的非常的簡單,而且mem_fun(&Base::clone)還支援polymorphism,相當漂亮,程式只要一行就解決,而且符合OCP,若未來有增加type,也不用再修改程式。

Conclusion
Modern C++ Design 8.7節指出這種使用clone的方式有兩個缺點:
1.必須在base class增加virtual clone(),若使用的是component而無法修改程式時,將無法使用這種方法。

2.每個derived class一定要去override base class的virtual clone(),若忘記override clone(),程式結果將有錯誤,而且compiler也不會提醒你。

Modern C++ Design因此提出了Clone Factory Pattern來解決這個問題,不過我還沒看懂這個pattern,但目前看起來使用clone()的方式還算不錯。

See Also
(原創) 若class中的data member有container,而且內含pointer時,也一定要big three!!(C/C++)

Reference
Andrei Alexandrescu,Modern C++ Design,Addison Weseley,2001
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: