zoukankan      html  css  js  c++  java
  • c++ 沉思录---代理类

    一、问题

      如何设计一容器能包含彼此不同而又相互关联的类的对象(处于完整的继承层次的类)?因为一般的数组容器都只能包含一种类型的对象。  

      假设有一个表示不同类型的交通工具的类的派生层次:    

    class Vehicle
    {
    public:
        virtual double weight () const = 0;
        virtual void start() = 0;
        //.....
    };
    
    class RoadVehicle : public Vehicle
    {
    public:
        /* data */
    };
    
    class AutoVehivle : public Vehicle
    {
    public:
        /* data */
    };
    
    class Aircraft : public Vehicle
    {
    public:
        /* data */
    };

      现在我们需要一个容器,这里使用数组表示,能够包含所有上述类的对象,Vehicle parkint_lot[100]; 这样肯定不对

        错误原因:1. Vehicle 是个抽象基类(含有纯虚函数),不能实例化对象

          2. 假设Vehicle能够实例化也不对,Parking_lot[num_vehicles++] = 派生类对象,这样的操作,会将派生类对象转化为一个Vehicle类的对象,会丢失所有Vehicle类中没有的成员。最后的结果是Parking_lot是Vehicle的集合。

    二、解决方案1(传统的解决方法)

       通过在数组中存储基类的指针,因为基类的指针转换为派生类的指针是容易且安全的。

       Vehicle*  Parking_lot[100];

        然后输入类似:

        Automonbile x =

         1: Parking_lot[num_vehicles++] = &x;  

         存在问题:如果x是局部变量,一旦变量x销毁了,Parking_lot 就不知道指向什么东西了。

         2:  Parking_lot[num_vehicles++] =  new Automobile(x);

        存在问题:为了解决1中问题,改用存储对象副本的指针。这种方法会带来一定的内存管理负担,其实我觉得还行,没那么严重,在需求没那么严格的情况下这种方法还是可以使用的。

     但是,这种只有当我们确定知道要放入parking_lot对象的静态类型后,才启作用!!!

     注意:用基类的指针或引用引用一个派生类对象时,由于派生类对象也是基类的对象,所以这样也是安全的但是只能引用基类中所拥有的成员,不能引用在派生类中定义的成员,否则编译器会报错。

    三、解决方案2(代理类)

      代理类:定义一个行为和Vehicle对象相似,而又潜在的表示为所有继承自Vehicle类的对象的东西,我们把这种类的对象称之为代理。

      在Vehicle类中添加虚复制函数

      virtual Vehicle* copy() const = 0;

      派生类中实现:  

      Vehicle*  派生类名称::copy() const{

        return new 派生类名称(*this);

      }

    class VehicleSurrogate
    {
    public:
        VehicleSurrogate();
        ~VehicleSurrogate();
        VehicleSurrogate(const Vehicle& v){
            vp(v.copy());
        }
    
        VehicleSurrogate(const VehicleSurrogate&);
        VehicleSurrogate& operator = (const VehicleSurrogate&);
    private:
        Vehicle* vp;
    };

     代理类的成员变量为Vehivle 类型的指针,参数为const Vehicle& 类型的构造函数,可以为任意继承自Vehicle的类的对象创建代理。

    使用方法:

    VehicleSurrogate paking_lot[100];

    Automobile x;

    Paking_lot[num_vehicles++] = x;   等价于 paking_lot[num_vehicles++] = VehicleSurrogate(x);

  • 相关阅读:
    Codeforces Round #409(Div.2)
    Require.js
    Javascript闭包
    修改GeoJson的网址
    获取服务器时间js代码
    JS中的call()和apply()方法
    什么是Javascript Hoisting?
    谁说 JavaScript 简单的?
    前端定时执行一个方法
    Jquery精妙的自定义事件
  • 原文地址:https://www.cnblogs.com/wxquare/p/5018118.html
Copyright © 2011-2022 走看看