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
相关产品推荐
相关产品推荐

