使用基类和派生类编写虚拟序列化函数

时间:2017-12-21 21:18:38

标签: c++ c++11

我正在处理一个处理汽车库存的项目。有一个基本的Vehicle类和派生的AdvancedVehicle类。我遇到了我的序列化函数的问题,这是一个虚函数。似乎每当函数被基类或派生类调用时,它只运行基本序列化函数。附件是Vehicle和AdvancedVehicle类的定义和实现。

/////////////////////////////// VEHICLE //////////////////////////////////
class Vehicle{
    friend ostream& operator<< (ostream& os, const Vehicle v) {
            v.Serialize(os);
            return os;
    }
public:
    Vehicle() = delete;
    Vehicle(string model, size_t year, float price) {
        m_model = model;
        m_year = year;
        m_baseprice = price;
        m_owner = NULL;
    }
    Vehicle(string model, size_t year, float price, const Client* owner) {
        m_model = model;
        m_year = year;
        m_baseprice = price;
        m_owner = new Client("");
        *m_owner = *owner;
    }
    Vehicle(const Vehicle& otherVehicle) {
        m_model = otherVehicle.m_model;
        m_year = otherVehicle.m_year;
        m_baseprice = otherVehicle.m_baseprice;
        m_owner = NULL;
    }
    Vehicle& operator= (const Vehicle& otherVehicle) {
        m_model = otherVehicle.m_model;
        m_year = otherVehicle.m_year;
        m_baseprice = otherVehicle.m_baseprice;
        m_owner = new Client("");
        *m_owner = *otherVehicle.m_owner;
        return *this;
    }
    void setPrice(float price) {
        m_baseprice = price;
    }
    void SetOwner(const Client* owner) {
        m_owner = new Client("");
        if(owner)
        {
            *m_owner = *owner;
        }
    }
    string GetModel() const { return m_model; }
    size_t GetYear() const { return m_year; }
    virtual float GetPrice() const { return m_baseprice; }
    Client* GetOwner() const { return m_owner; }
    virtual void Serialize(ostream& os) const {
        os << m_year << " ";
        os << m_model << " ";
        os << m_baseprice << " ";
        if(m_owner != NULL)
        {
            os << *m_owner << endl;
        }
    }
protected:
    string m_model;
    size_t m_year;

private:
 float m_baseprice;
 Client* m_owner;
};



/////////////////////////// ADVANCEDVEHICLE ///////////////////////////////
class AdvancedVehicle : public Vehicle{
    friend ostream& operator<< (ostream& os, const AdvancedVehicle AV) {
        AV.Serialize(os);
        return os;
    }
public:
    AdvancedVehicle() = delete;
    AdvancedVehicle(string model, size_t year, float price, vector<Sensor> sensors, const Client* owner):Vehicle (model, year, price){
        m_model = model;
        m_year = year;
        SetOwner(owner);
        setPrice(price);
        for(auto i = sensors.begin(); i != sensors.end(); i++)
        {
            int j = 0;
            AddSensor(sensors[j]);
            j++;
        }
    }
    AdvancedVehicle(string model, size_t year, float price, vector<Sensor> sensors):Vehicle (model, year, price){
        m_model = model;
        m_year = year;
        SetOwner(NULL);
        setPrice(price);
        for(auto i = sensors.begin(); i != sensors.end(); i++)
        {
            int j = 0;
            AddSensor(sensors[j]);
            j++;
        }
    }
    AdvancedVehicle(const AdvancedVehicle& otherAV):Vehicle( otherAV) {
        m_model = otherAV.m_model;
        m_year = otherAV.m_year;
        m_finalprice = otherAV.m_finalprice;
        SetOwner(NULL);
        for(auto i = otherAV.m_sensors.begin(); i != otherAV.m_sensors.end(); i++)
        {
            int j = 0;
            AddSensor(otherAV.m_sensors[j]);
            j++;
        }
    }
    AdvancedVehicle& operator=(const AdvancedVehicle& otherAV) {
        m_model = otherAV.m_model;
        m_year = otherAV.m_year;
        setPrice(otherAV.GetPrice());
        SetOwner(otherAV.GetOwner());
        for(auto i = otherAV.m_sensors.begin(); i != otherAV.m_sensors.end(); i++)
        {
            int j = 0;
            AddSensor(otherAV.m_sensors[j]);
            j++;
        }

        return *this;
    }
    void AddSensor(Sensor addedSensor) {
        m_sensors.push_back(addedSensor);
        m_finalprice += addedSensor.GetPrice();
    }
    virtual float GetPrice() const { return m_finalprice; }
    virtual void Serialize(ostream& os) const {
        os << m_year << " ";
        os << m_model << " ";
        os << m_finalprice << " ";
        if(GetOwner() != NULL)
        {
            os << GetOwner() << " ";
        }
        for(auto i = m_sensors.begin(); i != m_sensors.end(); i++)
        {
            os << &i << " ";
        }
        os << endl;
    }

private:
    vector<Sensor> m_sensors;
    float m_finalprice;
};

1 个答案:

答案 0 :(得分:2)

您的计划遇到the object slicing problemoperator<<按值获取Vehicle个对象。这意味着从传递给运算符的参数复制构造一个新的Vehicle对象。新对象是Vehicle,而不是AdvancedVehicle,即使传递给运算符的内容是AdvancedVehicle。该对象被称为切片,这就是调用Serialize()函数的基本版本的原因。

要解决此问题,您应修改operator<<重载,以便通过引用(Vehicle)获取Vehicle&。这将消除复制和切片。