(原創) 若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
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
相关文章推荐
- (原創) 若class中的data member有container,而且內含pointer時,也一定要big three!! (C/C++)
- (原創) 如何使用pointer和reference達成Polymorphism? (C/C++)
- 如何解决"ANSI C++ forbids data member `ip_opts' with same name as enclosing class"的编译错误
- (原創) 如何撰寫inline member function? (C/C++)
- 【C++】如何解决“pointer to incomplete class type is not allowed”。
- (原創) 如何刪除container中重複的element? (C/C++) (STL)
- Function Pointer of class member function (类的成员函数指针)
- static data member in a class
- warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
- (原創) 2 dim array該如何完全使用pointer存取? (C/C++) (C)
- (原創) 如何實現getElementByClassName()? (Web) (JavaScript)
- C++: member function pointer for SomeClass
- 15.含有指针成员的类的拷贝[ClassCopyConstructorWithPointerMember]
- 如何在vc6中MFC classwizard里Add Member variable name里增加Variable type?
- &class::data_member与&object.data_menber之间的差异
- Function Pointer of class member function (类的成员函数指针)
- (原創) 如何將container中的iterator,從一個值取代成另外一個值? (C/C++) (STL)
- (原創) 如何解決Rational Rose 2003關閉時,"MEM-BAD-POINTER"的錯誤訊息? (OO) (UML)
- Spring-Data-MongoDB保存对象的时候,如何不保存_class字段
- How do I declare and use a pointer to a class member function?