c++代理类
来源:互联网 发布:exif信息查看器 mac 编辑:程序博客网 时间:2024/06/05 18:38
其实代理模式跟这个差不多,对象A(相当于浏览器)不是直接访问对象C(相当Web服务器),而是通过一个中间对象B(相当于代理服务器)间接访问对象C。对象B则可以利用这一有利位置为A提供一个与C完全不同的接口,或做一些C本来不做的事!流程如下图所示:
A -----> B ------> C
这样B就是C的代理类,C可被称作实现类,A是客户代码。
==================
下面是源代码,一共4个文件。其中实现类成员函数为全部写成内联函数。
1. 实现类文件implementation.h:
// implementation.h --
// 2006-07-21 14:20
#ifndef IMPLEMENTATION_H_
#define IMPLEMENTATION_H_
class Implementation {
public:
Implementation(int v) { value = v; }
void setValue(int v) { value = v; }
int getValue() const { return value; }
private:
int value;
};
#endif
2. 代理类头文件interface.h:
// interface.h -- Interface类是Implementation类的代理类
// 2006-07-21 14:23
#ifndef INTERFACE_H_
#define INTERFACE_H_
class Implementation; // forward class declaration
class Interface { // Interface代理类
public:
Interface(int v);
void setValue(int v);
int getValue() const;
~Interface();
private:
Implementation * ptr;
};
#endif
3. 代理类实现文件interface.cpp:
// interface.cpp
// 2006-07-21 14:25
#include "implementation.h"
#include "interface.h"
Interface::Interface(int v) : ptr(new Implementation(v)) {
}
void Interface::setValue(int v) {
ptr->setValue(v);
}
int Interface::getValue() const {
return ptr->getValue();
}
Interface::~Interface() {
delete ptr;
}
4. 客户代码,这里只是一个主函数,使用代理模式,文件:useproxy.cpp:
// useproxy.cpp -- Use proxy class
// 2006-07-21 14:29
#include <iostream>
#include "implementation.h"
#include "interface.h"
using namespace std;
int main() {
Interface i(5);
cout << "Interface contains: " << i.getValue() << " before setValue/n";
i.setValue(10);
cout << "Interface contains: " << i.getValue() << " after setValue/n";
return 0;
}
=======================
运行结果:
Interface contains: 5 before setValue
Interface contains: 10 after setValue
Press any key to continue
=========================
说明:在useproxy.cpp文件中,只有一个Interface类对象,即代理类对象,所有的操作都是调用代理类的公有函数,间接操作实现类。
---------------------------------------
// 代理类 Demo// 将继承和容器共用,迫使我们要处理两个问题:// 控制内存分配和把不同类型的对象放入同一个容器中。// 代理类的每个对象都代表另一个对象,该对象可以是// 位于一个完整继承层次中的任何类的对象。通过在容器中// 用代理对象而不是对象本身来解决以上两个问题#include <process.h> // system()#include <iostream>using namespace std;// 所有交通工具的基类class Vehicle{public: virtual void start() = 0; // 动态复制 virtual Vehicle* copy() const = 0; // 虚析构函数 virtual ~Vehicle() {}};// 交通工具的代理类class VehicleSurrogate{public: // 无参构造函数,用于创建数组 VehicleSurrogate(); // 用Vehicle 及其派生类构造 VehicleSurrogate(const Vehicle&); ~VehicleSurrogate(); // 拷贝及赋值 VehicleSurrogate(const VehicleSurrogate&); VehicleSurrogate& operator=(const VehicleSurrogate&); // Vehicle 的方法 void start();private: Vehicle* p;};VehicleSurrogate::VehicleSurrogate() : p(0) {}VehicleSurrogate::VehicleSurrogate(const Vehicle& v) : p(v.copy()) {}VehicleSurrogate::VehicleSurrogate(const VehicleSurrogate& vs) : p(vs.p ? vs.p->copy() : 0) {}VehicleSurrogate & VehicleSurrogate::operator =(const VehicleSurrogate& vs){ if (p != vs.p) { delete p; p = vs.p ? vs.p->copy() : 0; } return *this;}VehicleSurrogate::~VehicleSurrogate() { delete p; }void VehicleSurrogate::start(){ if (p) p->start(); else cout << "Error" << endl;}class RoadVehicle : public Vehicle{public : void start() { cout << "RoadVehicle start." << endl; } Vehicle* copy() const { return (Vehicle*) new RoadVehicle(*this); } ~RoadVehicle() { }};class AutoVehicle : public RoadVehicle{public : void start() { cout << "AutoVehicle start." << endl; } Vehicle* copy() const { return (Vehicle*) new AutoVehicle(*this); } ~AutoVehicle() { }};void main(){ VehicleSurrogate pa[3]; RoadVehicle* prv = new RoadVehicle(); pa[0] = *prv; delete prv; pa[1] = AutoVehicle(); pa[2] = RoadVehicle(); pa[0].start(); pa[1].start(); pa[2].start(); system("pause");}
---------------------------------
问题:怎样设计一个c++容器,使它有能力包含类型不同而彼此相关的对象?
假设有一个表示不同种类的交通工具的类派生层次:
class Vehicle
{
public:
virtual double weight() const = 0;
virtual void start() = 0;
//.....
};
class RoadVehicle:public Vehicle {/*...*/};
class AutoVehicle:public RoadVehicle{/*....*/};
为了表述简单,使用数组来实现。由浅入深的提出以下几个方案:
方案一: 数组直接存储对象
Vehicle parking_lot[1000];
AutoVehicle x = /*.....*/
parking_lot[num_vehicles++] = x;
这里出现两个问题:
(1) Vehicle 为抽象基类,类Vehicle本身不会有对象,因此定义对象数组也就不可行了。
(2) 即使去掉类Vehicle中的纯虚函数,parking_lot 保存的是派生类裁剪后的对象,而不是所有继承自Vehicle类的对象的集合。
方案二:数组存储指针
Vehicle* parking_lot[1000];
AutoVehicle x = /*...*/;
parking_lot[num_vehicles++] = &x;
这里出现下面的问题:
我们存储在parking_lot中的是指向x的指针,如果x是个局部变量,一但变量x没有了,parking_lot就不知道指向什么东西了。我们可以改进一下,放入parking_lot中的值,不是指向原对象的指针,而是指向它们的副本的指针。在释放数组的时候,也释放其中所指向的全部对象。上面的代码可以改写为:
AutoVehicle x = /*...*/;
parking_lot[num_vehicles++] = AutoVehicle(x);
但是这样改也带来了动态内存管理的负担。另外,只有当我们知道要放到parking_lot中的对象的静态类型后,这种方法才能起作用。为了解决这个问题可以使用用虚复制函数, c++中处理未知类型的对象的方法就是使用虚函数。我们可以在类Vehicle中添加纯虚函数: virtual Vehicle* copy() const = 0; 则在派生类AutoVehicle 中 copy() 函数可以如下实现:
Vehicle* AutoVehicle::copy() const
{
return new AutoVehicle(*this);
}
然后就可以这样存储了: parking_lot[num_vehicles++] = x->copy(); 这里可以在运行时确定所要调用的copy函数。
方案三:定义代理类
方案二已经能较好的解决问题了,但是我们想避免显示的处理内存分配,又能保持类Vehicle在运行时绑定。这里采用代理类技术,就是定义一个行为和Vehicle对象相似,而又潜在地表示所有继承自Vehicle类的对象的东西。每个Vehicle代理都代表某个继承自Vehicle类的对象。只要该代理关联着这个对象,该对象就肯定存在。简单的实现了一下代理类,代码如下:
#include <iostream>
using namespace std;
class Vehicle
{
public:
virtual double weight() const = 0;
virtual Vehicle* copy() = 0;
virtual ~Vehicle() {}
};
class AutoVehicle:public Vehicle
{
public:
double weight() const
{
cout << "AutoVehicle weight" << endl;
return 1;
}
Vehicle* copy()
{
return new AutoVehicle(*this);
}
};
class RoadVehicle:public Vehicle
{
public:
double weight() const
{
cout << "RoadVehicle weight" << endl;
return 2;
}
Vehicle* copy()
{
return new RoadVehicle(*this);
}
};
class VehicleSurrogate
{
public:
VehicleSurrogate();
VehicleSurrogate(Vehicle&);
~VehicleSurrogate();
VehicleSurrogate(const VehicleSurrogate&);
VehicleSurrogate& operator=(const VehicleSurrogate&);
double weight() const;
private:
Vehicle *vp;
};
VehicleSurrogate::VehicleSurrogate():vp(0){} //空代理
VehicleSurrogate::VehicleSurrogate(Vehicle &v):vp(v.copy()){}
VehicleSurrogate::~VehicleSurrogate()
{
delete vp;
}
VehicleSurrogate::VehicleSurrogate(const VehicleSurrogate &v):
vp(v.vp ? v.vp->copy() : 0){}
VehicleSurrogate& VehicleSurrogate::operator=(const VehicleSurrogate &v)
{
if(this != &v)
{
delete vp;
vp = (v.vp ? v.vp->copy() : 0);
}
return *this;
}
double VehicleSurrogate::weight() const
{
if(vp == 0)
{
cout << "empty VehicleSurrogate" << endl;
}
else
{
return vp->weight();
}
}
int main()
{
VehicleSurrogate parking_lot[1000];
AutoVehicle x;
int num_vehicles = 0;
parking_lot[num_vehicles++] = x;
parking_lot[0].weight();
RoadVehicle y;
parking_lot[num_vehicles++] = VehicleSurrogate(y);
parking_lot[1].weight();
return 0;
}
个人感觉代理类最主要的好处就是隐藏的内存的分配,方案二中copy就已经可以实现了,只不过看起来不是那么顺眼。代理类用类来表示概念,通过在容器中代理对象而不是对象本身,解决了我们的问题。
- 类型的代理类(c++)
- C++代理类的使用
- delegate,C#,代理
- 【C++】Chapter4:代理模式
- Objective C--代理模式
- Objective C 代理模式
- Objective-c 代理模式
- object-c代理
- Object-C代理模式
- [c++]代理对象模式
- [c++]代理对象模式
- C#WebRequest设置代理访问
- Objective-C 代理的例子
- Objective-C协议与代理
- Objective-C:类别&代理
- ODI 12C 启动代理
- UE4 代理事件(C++)
- UE4 代理事件(C++)
- U-Boot顶层Makefile分析
- 杂项9
- 在用gui登录时,提示00,791的提示信息;口令无法在最初&天内更改
- 1-100不重复随机数的另一种思路
- Android 程序错误处理全局处理-捕获全局异常
- c++代理类
- 用Multisim分析二阶低通滤波器电路
- .net 连接Mysql封装
- java.lang.NoClassDefFoundError: com/opensymphony/xwork2/util/TextUtils
- Spring中常用的hql查询方法(getHibernateTemplate())(转)
- java.lang.ClassNotFoundException: com.opensymphony.xwork2.util.TextUtils
- CMarkup成员方法简介
- Can't match key hostname in map hosts.byname. Reason: No such key in map
- NoSQL学习资料