依然是学习<Ruminations On c++>的一点笔记。
问题的提出是:怎样设计一个C++容器,使它有能力包含类型不同而彼此相关的对象呢?
容器通常只能包含一种类型的对象,所以很难在容器中存储对象本身,最容易想到的就是存储指针(我目前在项目中使用的也是这种方法),这样虽然可以通过继承来处理类型不同的问题,但是也增加了内存分配的额外负担。
书中介绍了一种叫做代理的对象来解决这个问题,代理类是句柄类中最简单的一种,下面是一个简单的代理类实现:
// Surrogate.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #include <iostream> #include <vector> using namespace std; class Vehicle { public: virtual double weight()const =0; virtual void start()=0; virtual Vehicle* copy()const=0;//用来复制编译时类型未知的对象 virtual ~Vehicle()//以便调用正确的派生类析构函数 { } //... }; class RoadVehicle : public Vehicle { public: double weight()const { cout<<"RoadVehicle::weight()"<<endl; return 0; } void start() { cout<<"RoadVehicle::start()"<<endl; } Vehicle* copy()const { return new RoadVehicle(*this); } /**/ }; class AutoVehicle : public RoadVehicle { public: double weight()const { cout<<"AutoVehicle::weight()"<<endl; return 0; } void start() { cout<<"AutoVehicle::start()"<<endl; } Vehicle* copy()const { return new AutoVehicle(*this); } /**/ }; class Aircraft : public Vehicle { public: double weight()const { cout<<"Aircraft::weight()"<<endl; return 0; } void start() { cout<<"Aircraft::start()"<<endl; } Vehicle* copy()const { return new Aircraft(*this); } /**/ }; class Helicopter : public Aircraft { public: double weight()const { cout<<"Helicopter::weight()"<<endl; return 0; } void start() { cout<<"Helicopter::start()"<<endl; } Vehicle* copy()const { return new Helicopter(*this); } /**/ }; //代理类 class VehicleSurrogate { public: VehicleSurrogate(); VehicleSurrogate(const Vehicle&); ~VehicleSurrogate(); VehicleSurrogate(const VehicleSurrogate&); VehicleSurrogate& operator=(const VehicleSurrogate&); //来自类Vehicle的操作 double weight()const; void start(); private: Vehicle *vp; }; VehicleSurrogate::VehicleSurrogate():vp(0) { } VehicleSurrogate::VehicleSurrogate(const 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; } //直接转发给vp调用 double VehicleSurrogate::weight()const { if (vp==0) { throw "empty VehicleSurrogate.weight()"; } return vp->weight(); } void VehicleSurrogate::start() { if (vp==0) { throw "empty VehicleSurrogate.start()"; } vp->start(); } int _tmain(int argc, _TCHAR* argv[]) { vector<VehicleSurrogate> vecVS; RoadVehicle rv; Aircraft ar; AutoVehicle av; Helicopter hc; vecVS.push_back(rv); vecVS.push_back(ar); vecVS.push_back(av); vecVS.push_back(hc); vector<VehicleSurrogate>::iterator iter=vecVS.begin(); vector<VehicleSurrogate>::iterator iterEnd=vecVS.end(); while(iter!=iterEnd) { iter->weight(); iter->start(); iter++; } _CrtDumpMemoryLeaks(); return 0; }
下面是测试结果,使用VS2005发现有内存泄漏,暂时没找到原因。