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

问题:设计一个容器类,可以装载相关联的类。

一般容器类如vector或是list只能存放相同类型的类。这里我们想实现类似如下的功能:

    VehicleSurrogate parking_lot[100];
    Trunk x;
    parking_lot[0] = x;
    Car c;
    parking_lot[1] = c;

如果parking_lot存储的是指针,相对而言会容易的多,不过考虑到指针存储就有释放的问题,管理起来会很复杂,先不考虑。

解决方案:

通过设计一个抽象基类,所有关联类从此抽象类继承,然后使用一个代理来表示具体的类实例。如用vehicle表示抽象的交通工具,用start表示这些交通工具共同的能力:用car,trunk表示具体的交通工具,轿车,卡车。VehicleSurrogate用来表示具体的轿车,卡车。

1 设计相关联的类
// 头文件定义 Vehicle.h
class Vehicle
{
public:
    virtual double weight()const = 0;
    virtual void start() = 0;
    virtual Vehicle* copy() const = 0;
    virtual ~Vehicle() {}
};

class Trunk :public Vehicle
{
public:
    Trunk();
    virtual double weight() const;
    virtual void start();
    virtual Vehicle* copy() const;
private:
    double _weight;
};

class Car : public Vehicle
{
public:
    Car();
    virtual double weight() const;
    virtual void start();
    virtual Vehicle* copy() const;
private:
    double _weight;
};
// 实现文件 Vehicle.cpp
Trunk::Trunk()
{
    _weight = 20;
}

double Trunk::weight() const
{
    return _weight;
}

void Trunk::start()
{
    cout << "I'm Trunk,weight:"<<weight()<<".I start." << endl;
}

Vehicle* Trunk::copy() const
{
    return new Trunk(*this);
}

Car::Car()
{
    _weight = 5;
}

double Car::weight() const
{
    return _weight;
}

void Car::start()
{
    cout << "I'm car,weight:" << weight() << ".I start." << endl;
}

Vehicle* Car::copy() const
{
    return new Car(*this);
}

至此,创建了两种具体的交通工具,trunk和car,他们都可以克隆出自己。
下面用代理类来装载这些具体类。

class VehicleSurrogate {
public:
    VehicleSurrogate();
    VehicleSurrogate(const Vehicle &);
    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(const VehicleSurrogate &vs)
    : vp(vs.vp ? vs.vp->copy() : 0) {}

VehicleSurrogate &VehicleSurrogate::operator=(const VehicleSurrogate &vs)
{
    if (&vs != this)
    {
        delete vp;
        vp = (vs.vp ? vs.vp->copy() : 0);
    }
    return *this;
}

double VehicleSurrogate::weight() const
{
    if (vp == 0)
        throw "abc";
    return vp->weight();
}

void VehicleSurrogate::start()
{
    if (vp == 0)
        throw "abc";
    return vp->start();
}

至此,定义VehicleSurrogate parking_lot[100]后,已经可以装载具体的交通工具卡车和轿车了。
在进行:

    Trunk x;
    parking_lot[0] = x;

实际上是用到了赋值函数VehicleSurrogate &operator=(const VehicleSurrogate &);
从而实现了将不同的类赋给容器
附测试代码:

#include "stdafx.h"
#include <iostream>
using namespace std;

#include "VehicleSurrogate.h"

int main()
{
    int num_vehicles = 0;
    VehicleSurrogate parking_lot[100];
    Trunk x;
    parking_lot[0] = x;
    Car c;
    parking_lot[1] = c;
    parking_lot[0].start();
    parking_lot[1].start();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永远的麦田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值