C++ 代理类

原文 http://blog.csdn.net/kongying168/article/details/7220346


C++代理类的使用

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

class Vehicle
{
public:
    Vehicle(){}
    virtual string getName()= 0;
}:

class Car : public Vehicle
{
public:
   Car(){}
   virtual string getName(){}
};

class Bike : public Bike
{
public:
    Bike(){}
     virtual string getName(){}
}:

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

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

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

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

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

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

还有一种写法就是vector<Vehicle*> parkinglot.

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

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

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


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

 

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

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

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

#include "stdafx.h"
#include <iostream>  
#include <string>  

using namespace std;  

class Vehicle  
{  
public:  

	Vehicle(){}  
	virtual string getName() = 0;  
	virtual Vehicle* copy() const = 0;  
	virtual ~Vehicle(){} //虚析构函数是为了支持多态.但是本例中并不需要.  
private:  
};

class Car :public Vehicle  
{  
public:  
	Car(){}  
	virtual string getName() {return "car";}  
	virtual Vehicle* copy() const {return new Car;}  
	virtual ~Car(){}  


};  

class Bike : public Vehicle  
{  
public:  
	Bike(){}  
	virtual string getName(){return "bike";}  
	virtual Vehicle* copy()const {return new Bike;}  
	virtual ~Bike(){}  
};  

class VehicleSurrogate  
{  
public:  
	VehicleSurrogate():p(0){}  
	VehicleSurrogate(const Vehicle& v):p(v.copy()){}  
	VehicleSurrogate(const  VehicleSurrogate &vs):p(vs.p ? vs.p->copy() : 0){}  
	VehicleSurrogate & operator=(const VehicleSurrogate &vs);  
	string getName(){return p->getName();}  
	~VehicleSurrogate(){delete p;}  
private:  
	Vehicle *p;  
};  

VehicleSurrogate & VehicleSurrogate::operator=(const VehicleSurrogate&vs)  
{  
	if (this != &vs) //在删除p之前一定得记得判断vs和this是不是同一个,否则会有问题  
	{  
		delete p;  
		p = vs.p->copy();  
	}  
	return *this;  
}  



int main()  
{  
	Car c;  
	Bike b;  

	VehicleSurrogate vs1(c);  
	std::cout << vs1.getName() << std::endl;  
	VehicleSurrogate vs2(b);  
	std::cout << vs2.getName() << std::endl;  

	return 0;  
}  


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

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

car

bike.

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值