《C++沉思录》第五章---代理类

原创 2006年06月08日 14:52:00

          在编程过程中可能要把不同的对象(这些对象可能存在一些关系:继承)放到一个容器里边,我们都知道一个基类的指针可以指向子类的一个实例,我们就在这里有用一个基类的指针使其指向不同的实例,并把这些指针放到一个容器内。我把这一章内的讲解的例子整理了一下,并通过了测试。测试的环境是(VS2003)

 class vehicle
{
public:
 virtual ~vehicle(void) {}
 virtual double weight(void) const = 0;
 virtual void start(void) = 0;
 virtual vehicle* copy(void) const = 0;
};//vehicle是一个抽象类,不可以实例化

class RoadVehicle : public vehicle
{
public:
 RoadVehicle(void) {}
 ~RoadVehicle(void) {}
 double weight(void) const { cout<<"RoadVehicle weight"<<endl; return 0; }
 void start(void) { cout<<"RoadVehicle start"<<endl; }
 vehicle* copy(void) const { return new RoadVehicle(*this); }
};

class AutoVehicle : public RoadVehicle
{
public:
 AutoVehicle(void) {}
 ~AutoVehicle(void) {}
 double weight(void) const { cout<<"AutoVehicle weight"<<endl; return 0;}
 void start(void) { cout<<"AutoVehicle start"<<endl; }
 vehicle* copy(void) const { return new AutoVehicle(*this); }
};

class AirCraft : public vehicle
{
public:
 AirCraft(void) {}
 ~AirCraft(void) {}
 double weight(void) const { cout<<"AirCraft weight"<<endl; return 0; }
 void start(void) { cout<<"AirCraft start"<<endl; }
 vehicle* copy(void) const { return new AirCraft(*this); }
};

class Helicopter : public AirCraft
{
public:
 Helicopter(void) {}
 ~Helicopter(void) {}
 double weight(void) const { cout<<"Helicopter weight"<<endl; return 0; }
 void start(void) { cout<<"Helicopter start"<<endl; }
 vehicle* copy(void) const { return new Helicopter(*this); }
};

///下面就是代理类了,通过这个类来访问不同对象的方法。

class VehicleSurrogate
{
public:
 VehicleSurrogate(void) : vp(0) {}
 VehicleSurrogate(const vehicle &v) : vp(v.copy()) {};//构造不同的实例,在程序的编译期间是不知道会是个什么样的对象
 ~VehicleSurrogate(void) { delete vp; }
 VehicleSurrogate(const VehicleSurrogate &v) : vp(v.vp ? v.vp->copy() : 0) { }
 VehicleSurrogate& operator=(const VehicleSurrogate &v)
 {
  if (this != &v)
  {
   delete vp;
   vp = (v.vp ? v.vp->copy() : 0);
  }
  return *this;
 }
 double weight(void)
 {
  if (vp == 0)
  {
   cout<<"weight vp is NULL"<<endl;
  }
  return vp->weight();
 }
 void start(void)
 {
  if (vp == 0)
  {
   cout<<"start vp is NULL"<<endl;
  }
  return vp->start();
 }
private:
 vehicle *vp;
};
int _tmain(int argc, _TCHAR* argv[])
{
 VehicleSurrogate parking_lot[2];
 Helicopter x;
 AirCraft y;
 parking_lot[0] = x;
 parking_lot[1] = y;
 parking_lot[0].weight();
 parking_lot[1].start();
 return 0;
}

Output:

Helicopter weight

AirCraft start

   在这个程序中,存储到容器中的对象都是原来对象的一个副本(即原对象的一个拷贝),一定要复制这些对象吗?答案是否定的,我们可以存储这些对象的句柄,使用句柄同样可以保持原来的对象的多态行为,却是我们减少了不必要的拷贝,何乐而不为呢?

 

 

《C++沉思录》第五章:C++代理类的使用

C++代理类的使用 这篇博客是我在学习C++沉思录的第5章做的笔记。 本文主要讲了C++中代理类的使用方法和使用情况。   所谓代理类,即surrogate.为...
  • wxfsjtu
  • wxfsjtu
  • 2017年12月06日 10:18
  • 4

对C++沉思录中代理类实现的质疑和修改

原文地址:http://blog.chinaunix.net/uid-25909722-id-2182249.html GDC注:本来看《C++沉思录》第五章后,想自己总结一下的,但是太懒,...

《C++沉思录》第5章 代理类——(整理)

《C++沉思录》第5章 代理类——(整理) 转自:http://hi.baidu.com/cndx100/blog/item/e009cd46e3a9650f6a63e5e4.html 200...

C++沉思录代理类

前几天看的时候没看明白书里头说的对copy的调用都是虚调用的意思。我还理解成虚调用就相当于啥都没干,然后就百思不得其解了。难道是因为翻译的问题,可惜木有英文版,本来对照着看看 今天跑了下代码,其实就...

《C++沉思录》读书笔记【一】:代理类

C++代理类是为了解决这样的问题: 容器通常只能包含一种类型的对象,所以很难在容器中存储对象本身。怎样设计一个c++容器,使它有能力包含类型不同而彼此相关的对象? 代理运行起来和他所代表的对象基本相同...

C++沉思录-第5章 代理类

问题:设计一个容器类,可以装载相关联的类。一般容器类如vector或是list只能存放相同类型的类。这里我们想实现类似如下的功能: VehicleSurrogate parking_lot[10...

C++沉思录读书笔记(5章)-代理类

问题描述:如何设计一个容器,能使得它能包含类型不同但是彼此相关的对象? 问题描述:如何复制编译时类型未知的对象? 解决方案一:使用容器存储指向对象的指针,通过继承来处理类型不同的对象。 ...

《C++沉思录》——类设计核查表、代理类、句柄类

《C++沉思录》——类设计核查表、代理类、句柄类

C++ 沉思录》阅读笔记——类的反思

类这个概念无非是数据和方法的集合,为什么我一直困惑呢?为什么不弄清楚呢? C++中的类这个概念里有4个函数比较特殊,像我这种以前有C经验的人可能一时难以适应,它们是构造函数、析构函数、复制构造函...

《C++ 沉思录》阅读笔记——句柄类

在上一篇博文里,我介绍了代理类的相关内容,如果记性好的朋友,应该已经对代理类有了比较深入的认识。在设计代理类的过程中,我们遇到的核心问题是:内存的分配和编译时类型未知对象的绑定。我们通过让所有子类自定...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《C++沉思录》第五章---代理类
举报原因:
原因补充:

(最多只允许输入30个字)