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

Writing a Virtual Serialize Function with a Base and Derived Class

本文关键字:虚拟 序列化 函数 派生      更新时间:2023-10-16

我正在研究一个项目来处理汽车清单。有一个基本车辆类和一个派生的高级车辆类。我正在使用我的序列化函数遇到问题,这本来是虚拟函数。似乎每当函数由基本或派生类调用时,它都只能运行base serialize函数。附件既是车辆和高级车辆类的定义和实现。

/////////////////////////////// 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;
};

您的程序正在遭受对象切片问题的困扰。operator<<通过Value 采用Vehicle对象。这意味着一个新的Vehicle对象是从传递给操作员的参数中复制构造的。新对象是Vehicle,而不是AdvancedVehicle,即使传递给操作员的内容是AdvancedVehicle。据说该对象已切成薄片,这就是为什么称为Serialize()函数的基本版本。

要解决这个问题,您应该修改operator<<过载以通过参考(Vehicle&)进行Vehicle。这将消除副本和切片。