c++ 代理类

 

C++代理类的使用

所谓代理类,即surrogate.为什么要使用它呢,简单的举个例子.

 1 class Vehicle
 2 {
 3 public:
 4     Vehicle(){}
 5     virtual string getName()= 0;
 6 }:
 7
 8 class Car : public Vehicle
 9 {
10 public:
11    Car(){}
12    virtual string getName(){}
13 };
14
15 class Bike : public Bike
16 {
17 public:
18     Bike(){}
19      virtual string getName(){}
20 }:

有简单的3个类,继承关系也很简单.

如果现在要定义个parkinglot.那该如何存呢?

有人会说,直接一个Vehicle数组就好了.即Vehicle parkinglot[500];

但是这里是会有很大错误的!

首先显然Vehicle是一个虚基类,虚基类是不会有对象的.

其次,这种数组的写法不能表现出任何多态的性质.(多态只能由指针和引用来体现)

还有一种写法就是vector parkinglot.

这种写法也是可以的.但是会有动态内存管理的麻烦.而且要是出现了如下的代码

void wrong_code(vector &parkinglot)
{
   Car c;
   parkinglot.push_back(&c);//将c插入到parkinglot内
}

int main()
{
  vector parkinglot;
  wrong_code(parkinglot);
  parkinglot[0].getName(); //Oops!!parkinglot内存的地址指向了一块被销毁的内存
 
}

会造成程序运行的时候出现runtime error!

 

在这种大前提下,代理类就顺势而生了.

顾名思义,代理类就是指某个基类以及其子类的代理,其功能是使之能在容器中也表现出多态性.而没有动态内存管理的烦恼.

现在定义Vehicle以及子类的代理类VehicleSurrogate.

  1 /*
  2  * =====================================================================================
  3  *
  4  *       Filename:  surrogate.cpp
  5  *
  6  *    Description:  chapter 5 in book
  7  *
  8  *        Version:  1.0
  9  *        Created:  12/04/2011 07:04:12 AM
 10  *       Revision:  none
 11  *       Compiler:  gcc
 12  *
 13  *         Author:  summer (), [email protected]
 14  *        Company: 
 15  *
 16  * =====================================================================================
 17  */
 18
 19 /*
 20  * =====================================================================================
 21  *        Class:  Vehicle
 22  *  Description: 
 23  * =====================================================================================
 24  */
 25
 26 #include
 27 #include
 28
 29 using namespace std;
 30
 31 class Vehicle
 32 {
 33     public:
 34        
 35         Vehicle(){}
 36         virtual string getName() = 0;
 37         virtual Vehicle* copy() const = 0;
 38         virtual ~Vehicle(){} //虚析构函数是为了支持多态.但是本例中并不需要.
 39     private:
 40        
 41
 42 };
 43
 44 class Car :public Vehicle
 45 {
 46 public:
 47     Car(){}
 48     virtual string getName() {return "car";}
 49     virtual Vehicle* copy() const {return new Car;}
 50     virtual ~Car(){}
 51    
 52
 53 };
 54
 55 class Bike : public Vehicle
 56 {
 57 public:
 58     Bike(){}
 59     virtual string getName(){return "bike";}
 60     virtual Vehicle* copy()const {return new Bike;}
 61     virtual ~Bike(){}
 62 };
 63
 64 class VehicleSurrogate
 65 {
 66 public:
 67     VehicleSurrogate():p(0){}
 68     VehicleSurrogate(const Vehicle& v):p(v.copy()){}
 69     VehicleSurrogate(const  VehicleSurrogate &vs):p(vs.p ? vs.p->copy() : 0){}
 70     VehicleSurrogate & operator=(const VehicleSurrogate &vs);
 71     string getName(){return p->getName();}
 72     ~VehicleSurrogate(){delete p;}
 73 private:
 74     Vehicle *p;
 75 };
 76
 77 VehicleSurrogate & VehicleSurrogate::operator=(const VehicleSurrogate&vs)
 78 {
 79   if (this != &vs) //在删除p之前一定得记得判断vs和this是不是同一个,否则会有问题
 80    {
 81       delete p;
 82       p = vs.p->copy();
 83    }
 84    return *this;
 85 }
 86
 87
 88
 89 int main()
 90 {
 91    Car c;
 92    Bike b;
 93
 94    VehicleSurrogate vs1(c);
 95    std::cout << vs1.getName() << std::endl;
 96    VehicleSurrogate vs2(b);
 97    std::cout << vs2.getName() << std::endl;
 98
 99   return 0;
100
101 }

为此还改造了一下Vehicle,使其支持复制到我们的代理类中.

程序的运行结果也很清晰,正如我们预料的那样.分别是

car

bike.

代码很简单,不用解释也能看得清楚.

很明显,有了代理类之后,parkinglot也就不难定义了.

而通过这样的写法,也简化了我们在vector这种情况下的动态管理内存的麻烦.
后记:

       在看到代理类的优点的时候,我们也必须正视他的缺点.即每次使用都得要进行复制,如果对于某些特别大的类来说,复制并不是一个明智的选择.

       在接下来我会介绍handle类,解决了这个方面的问题.

 

引自:博客园

你可能感兴趣的:(技术分享,c++,string,class,iostream,compiler,delete)