You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何声明可存储两种StorageInfo子类实例的类成员变量

你原本的实现不可行,会触发对象切片问题:基类对象storage_info_仅能容纳基类自身的成员,赋值子类实例时会丢弃子类所有独有内容,后续调用的永远是基类的方法,无法实现动态切换效果。

你可以通过C++面向对象的多态特性实现需求,改造步骤如下:

步骤1:将基类StorageInfo改造为抽象接口

修改StorageInfo.hpp,将所有对外公共方法声明为虚函数,同时添加虚析构函数避免内存泄漏:

#include <cstdint>

class StorageInfo {
public:
    // 必须添加虚析构函数,否则子类实例销毁时会出现内存泄漏
    virtual ~StorageInfo() = default;

    // 所有对外方法声明为纯虚函数,强制子类实现
    virtual void initializeStorage() = 0;
    virtual void updateStorageInfo() = 0;
    virtual int popLocation() = 0;
    virtual int peakLocation() = 0;
    virtual uint16_t totalSize() = 0;
    virtual uint16_t remainingSize() = 0;
    // 其他对外方法同样声明为纯虚函数
private:
    // 基类不需要额外私有成员,若有原有公共逻辑可以保留,对应方法改为普通虚函数提供默认实现即可
};

步骤2:调整子类的继承声明

两个子类需要改为公有继承自基类,重写的方法添加override关键字让编译器校验重写正确性:

// StorageInfoA.hpp
#include "StorageInfo.hpp"

class StorageInfoA: public StorageInfo {
public:
    void initializeStorage() override;
    void updateStorageInfo() override;
    int popLocation() override;
    int peakLocation() override;
    uint16_t totalSize() override;
    uint16_t remainingSize() override;
    // 其他方法声明
private:
    // 子类私有成员
};

StorageInfoB的声明逻辑与StorageInfoA完全一致。

步骤3:修改device类的成员变量类型

将原本的基类对象改为智能指针,避免手动管理内存:

// device.hpp
#include <memory>
#include "StorageInfo.hpp"

class device {
public:
    // 原有公共内容
private:
    // 原有私有内容
    std::unique_ptr<StorageInfo> storage_info_;
    // 原有其他私有内容
};

步骤4:调整初始化与调用逻辑

构造函数中根据条件创建对应子类实例,调用时改为指针调用语法即可:

// device.cpp 构造函数内的逻辑
if(save_to_cache){
    storage_info_ = std::make_unique<StorageInfoA>();
} else {
    storage_info_ = std::make_unique<StorageInfoB>();
}

// 后续调用无需修改逻辑,仅需要把.改为->即可
storage_info_->updateStorageInfo();

如果你的项目使用C++17及以上版本,也可以用std::variant实现静态多态,适合不想引入虚函数开销的场景,但需要额外适配调用逻辑,改造成本高于上述动态多态方案。


内容的提问来源于stack exchange,提问作者MochaPower19

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:36:06