随笔 - 224  文章 - 41  trackbacks - 0
<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

享受编程

常用链接

留言簿(11)

随笔分类(159)

随笔档案(224)

文章分类(2)

文章档案(4)

经典c++博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜

TitleType text here...
 

        这个例子可以看做是对STL容器设计从头到尾的一种讨论,我承认到最后版本也和STL中的容器有很大的差距,但是我们发现在这样的讨论有利于我们更进一步的对STL的设计有更深一步的了解。首先,假设我们想把一个堆类放到一个数组中,例如是一些表示不同类型的交通工具,当然不同的交通工具在这里都派生之一个基础类:

#include <iostream>

class Vehicle 

{
public:

       
virtual void start() =0;

       
virtual double weight() const = 0;

       Vehicle();

       
virtual ~Vehicle();

}
;

Class RoadVehicle: 
public Vehicle{}

Class AutoVehicle: 
public Vehicle{}

等等,所有派生之Vehicle类都必须实现这些虚拟函数否则无法实例化。

现在想对这些交通工具进行管理把它放在一个数组中如下:


 

Automatebile x = /* */

Vehicle parking_lot[
100];

Parking_lot[num_vehicles
++]=x;

    当然这里有一个严重的问题,error C2259: 'Vehicle' : cannot instantiate abstract class due to following members: Vehicle有多个的纯虚函数这里是无法实例化的,即使可以这里的x其实是被裁剪了就退化成Vehicle了,并不是我们所想的让他实现动态联编。这是初学的时候经常碰到的一些小问题,可以通过指针解决。

Vehicle* parking_lot[100];

Automatebile x 
= /**/

Parking_lot[num_vehiles
++]=&x;

        这样一来就可以解决动态联编的问题了,同时也出现了新的问题,这里的x是局部变量当x的生命周期到了的时候,那么Parking_lot[/* */]什么也不是了。有人也提出了用动态申请的方法,Parking_lot[num_vehiles++] = new Automoblie(x);但是申请的这块内存该由谁来释放呢!一个好的解决办法就是通过代理让它了管理内存的释放问题。这里在每个类中都加入一个拷贝自己的函数。如下:

 

class Vehicle 

{
public:

       
virtual Vehicle* copy() const =0;

       
virtual void start() =0;

       
virtual double weight() const = 0;

       Vehicle();

       
virtual ~Vehicle();

}
;

Vehicle
* RoadVehicle::copy() const

{
       
return new RoadVehicle(*this);

}

 

建立一个代理类如下:

 

template <class T>

class VehicleSurrogate 

{
public:
       
//constructor

       VehicleSurrogate(
const VehicleSurrogate&);

       VehicleSurrogate(
const T&);

       VehicleSurrogate();

       
virtual ~VehicleSurrogate();

       
//override the operator

       VehicleSurrogate
<T>& operator =(const VehicleSurrogate &v);

       T
* operator->();
private:    
       
//the point of the member

       T
* vp;

}
;

这个类中有一个指向交通工具的指针T* vp,就可以用来存放任何一个派生至Vehicle的类,可以建立一个数组:

VehicleSurrogate<Vehicle> parking_lot[100];
parking_lot[num_vehicles
++= VehicleSurrogate<Vehicle>(RoadVehicle());

在往parking_lot放东西时,用copy函数进行动态的分配一个对象,这个动态对象的释放是由VehicleSurrogate来管理的,不用自己操心,不会引起内存的泄露问题。下面看看VehicleSurrogate类的实现:

 

//in order to achieve Array 

template 
<class T>

VehicleSurrogate
<T>::VehicleSurrogate():vp(0)

{

}

//delete the point Prevent memory leak

template 
<class T>

VehicleSurrogate
<T>::~VehicleSurrogate()

{

       
if (vp)

              delete vp;

}


//new a class to the vp

template 
<class T>

VehicleSurrogate
<T>::VehicleSurrogate(const T& v):vp(v.copy())

{     

}


template 
<class T>

VehicleSurrogate
<T>::VehicleSurrogate(const VehicleSurrogate<T> & v):vp(v.vp? v.vp->copy():0)

{

}

template 
<class T>

VehicleSurrogate
<T>& VehicleSurrogate<T>::operator =(const VehicleSurrogate &v)

{
       
if (this != &v)//we must pay attention to yourself

       
{

              delete vp;

              vp 
= (v.vp?v.vp->copy():0);

       }

       
return *this;
}



//this is the different to the book, in order to dislodge the function start and weight

template 
<class T>

T
* VehicleSurrogate<T>::operator->()

{
       
return vp;
}

这里我想说的是,这个类的实现和专业的STL容器是有一定的差距的,每次给容器放东西的时候都有调用copynew一个类,这样的操作有点浪费时间了。
代码

posted on 2009-03-08 16:37 漂漂 阅读(294) 评论(0)  编辑 收藏 引用 所属分类: STL

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理