More Effective C++ (虚拟构造函数)

在了解代码之前,请先仔细阅读这些概念:

<1>虚构造函数:

一种允许你做一些 C++不直接支持的事情的用法。

你可能通过虚函数 virtual clone()(对于默认拷贝构造函数)或虚函数 virtual create()(对于默认构造函数),得到虚构造函数产生的效果。


<2>虚拟拷贝构造函数:

一种特殊的虚拟构造函数――虚拟拷贝构造函数――也有着广泛的用途。

虚拟拷贝构造函数能返回一个指针,指向调用该函数的对象的新拷贝。

因为这种行为特性,虚拟拷贝构造函数的名字一般都是copySelf,cloneSelf或者是像下面这样就叫做clone。


<3>协变返回类型:

注意:下述代码的实现利用了被采纳的较宽松的虚拟函数返回值类型规则。

被派生类重定义的虚拟函数不用必须与基类的虚拟函数具有一样的返回类型。

如果函数的返回类型是一个指向基类的指针(或一个引用),那么派生类的函数可以返回一个派生类的指针(或引用)。

这不是C++的类型检查上的漏洞,它使得有可能声明像虚拟构造函数这样的函数。

这就是为什么Circle 的clone函数能够返回Circle * 和 Square 的clone也能够返回Square *的原因,即使Shape 的clone返回值类型却为Shape *。

备注:根据坊间记录,以前的编译器是不支持这个东东的。


<4>虚拟构造函数

因为它能建立新对象,它的行为与构造函数相似,而且因为它能建立不同类型的对象,我们称它为虚拟构造函数。

虚拟构造函数是指能够根据输入给它的数据的不同而建立不同类型的对象。

虚拟构造函数在很多场合下都有用处,从磁盘(或者通过网络连接,或者从磁带机上)读取对象信息只是其中的一个应用。

示例代码1如下:

 1 #include<iostream>
 2 using  namespace std;
 3 class Shape 
 4 {
 5 public:
 6     virtual ~Shape() { }                  // 虚析构函数
 7      
 8 //  使用默认拷贝构造函数 ,more effective c++中成为虚拟拷贝构造函数  。涉及"协变返回类型"
 9     virtual Shape* clone()  const = 0;  
10 //  使用默认构造函数
11     virtual Shape* create() const = 0;     
12 };
13 
14 class Circle : public Shape 
15 {                
16 public:
17     Circle()
18     {
19         cout<<"Construction   Circle  "<<this<<endl;
20     }
21 public:
22     //在 clone() 成员函数中,代码 new Circle(*this) 调用 Circle 的默认拷贝构造函数来复制this的状态到新创建的Circle对象
23     Circle* clone()  const 
24     { 
25         return new Circle(*this);
26     }   
27     //在 create()成员函数中,代码 new Circle() 调用Circle的默认构造函数。
28     Circle* create() const 
29     { 
30         return new Circle();
31     }   
32     //析构函数
33     ~Circle()
34     {
35         cout<<"Destroy  Circle  "<<this<<endl;
36     }
37 
38 };
39 
40 class Square : public Shape 
41 {
42 public:    
43     Square()
44     {
45         cout<<"Construction   Square  "<<this<<endl;
46     }
47 public:
48     //在clone()成员函数中,代码 new Square(*this) 调用Square的默认拷贝构造函数来复制this的状态到新创建的Square对象
49     Square* clone()  const 
50     { 
51         return new Square(*this);
52     }
53     //在 create()成员函数中,代码 new Square() 调用Square的默认构造函数。
54     Square* create() const 
55     { 
56         return new Square();
57     }
58     //析构函数
59     ~Square()
60     {
61         cout<<"Destroy  Square  "<<this<<endl;
62     }
63 
64 };
65 //虚构造函数
66 void userCode(Shape &s)
67 {
68     Shape* s2 = s.create();     
69     Shape* s3 = s.clone();   
70 
71     delete s2;    // 在此处,需要虚析构函数
72     delete s3;
73 }
74 
75 int main() 
76 {
77     Circle c;
78     userCode(c);
79     
80     Square s;
81     userCode(s);
82 }
83 
84 /*
85  *运行结果与分析:
86 Construction   Circle  003EF8D8  调用Circle构造函数创建对象c
87 Construction   Circle  00234B98  userCode函数中s.create()函数调用Circle构造函数创建新对象
88 Destroy  Circle  00234B98  析构新构造对象
89 Destroy  Circle  00234BD8  析构克隆对象
90 Construction   Square  003EF8CC  调用Square构造函数创建对象s
91 Construction   Square  00234B98  userCode函数中s.create()函数调用Square构造函数创建新对象
92 Destroy  Square  00234B98  析构新构造对象
93 Destroy  Square  00234BD8  析构克隆对象
94 Destroy  Square  003EF8CC  析构对象s
95 Destroy  Circle  003EF8D8  析构对象c
96 */

 示例代码2如下:

  1 #include<iostream>
  2 using  namespace std;
  3 
  4 class Object
  5 {
  6 public:
  7     Object()
  8     {}
  9     virtual ~Object()
 10     {}
 11     virtual void print() const = 0;
 12 public:
 13     virtual Object* CloneSelf()  const = 0; 
 14     virtual Object* CopySelf() const = 0;
 15 };
 16 
 17 class Int:public Object
 18 {
 19 private:
 20     int value;
 21 public:
 22     Int(int x = 0):value(x)
 23     {}
 24     ~Int()
 25     {}
 26     void print() const
 27     {
 28         cout<<value<<endl;
 29     }
 30 public:
 31     Int* CloneSelf() const 
 32     { 
 33         return new Int();
 34     }
 35     Int* CopySelf() const  
 36     {
 37         return new Int(*this);
 38     }
 39 };
 40 class Char:public Object
 41 {
 42 private:
 43     char value;
 44 public:
 45     Char(char x='h'):value(x)
 46     {}
 47     ~Char()
 48     {}
 49     void print() const
 50     {
 51         cout<<value<<endl;
 52     }
 53 public:
 54     Char* CloneSelf() const 
 55     { 
 56         return new Char();
 57     }
 58     Char* CopySelf() const  
 59     {
 60         return new Char(*this);
 61     }
 62 };
 63 class Double:public Object
 64 {
 65 private:
 66     double value;
 67 public:
 68     Double(double x=12.34):value(x)
 69     {}
 70     ~Double()
 71     {}
 72     void print() const
 73     {
 74         cout<<value<<endl;
 75     }
 76 public:
 77     Double* CloneSelf() const 
 78     { 
 79         return new Double();
 80     }
 81     Double* CopySelf() const  
 82     {
 83         return new  Double(*this);
 84     }
 85 };
 86 
 87 class SeqList
 88 {
 89     Object *data[10];
 90     int MaxSize;
 91     int len;
 92 public:
 93     //虚拟构造函数
 94     Object * CloneObj(Object &ob)
 95     {
 96         return ob.CloneSelf();
 97     }
 98     //虚拟拷贝构造
 99     Object * CopyObj(Object &ob)
100     {
101         return ob.CopySelf();
102     }
103 public:
104     SeqList()
105     {
106         MaxSize = 10;
107         for(int i = 0; i < MaxSize; ++i)
108         {
109             data[i]=NULL;
110         }
111         len = 0; 
112     }
113 
114     ~SeqList()
115     {}
116     void pushClone(Object &ob)
117     {
118         data[len++] = CloneObj(ob);
119     }
120     void pushCopy(Object &ob)
121     {
122         data[len++] = CopyObj(ob);
123     }
124     void print() const
125     {
126         for(int i = 0; i < len; ++i)
127         {
128             data[i]->print();
129         }
130         cout<<endl;
131     }
132 };
133 void main()
134 {
135     SeqList mylist;
136     Int intObj;
137     Char charObj;
138     Double douObj;
139     mylist.pushClone(intObj);
140     mylist.pushClone(charObj);
141     mylist.pushClone(douObj);
142     mylist.pushCopy(intObj);
143     mylist.pushCopy(charObj);
144     mylist.pushCopy(douObj);
145     mylist.print();
146 }
147 /*
148 0
149 h
150 12.34
151 0
152 h
153 12.34
154  */

Good Good Study, Day Day Up.

顺序  选择  循环  坚持

posted @ 2013-01-06 11:06  kaizenly  阅读(1361)  评论(0编辑  收藏  举报
打赏