C++反菱形模式下实现数据实例共享的可行方案问询
问题:让TableDerived的data基类部分与TableBase的data指向同一物理实例
类的转换(构造函数)关系:
DataBase ----> DataDerived | | V V TableBase ----> TableDerived
每个Table类都拥有一个data属性。
问题描述
当obj为TableDerived类型时,如何让obj.data::DataBase与obj.TableBase::data指向完全相同的物理实例?
当前实现代码
struct DataBase{ int i{}; }; struct DataDerived : DataBase{ int j{}; DataDerived(DataBase&& d):DataBase(std::move(d)){} }; // 以上代码逻辑清晰,以下代码存在疑问 struct TableBase{ DataBase data; // 不得存储在堆上!! }; struct TableDerived: TableBase{ DataDerived data; };
限制条件
- 不希望Table类继承自Data类;
- 不使用动态内存分配;
- 要求四个类均可独立完整存在(非聚合类型,仅包含属性)。
已尝试方案
- 使用
shared_ptr会引入动态内存分配,不符合需求; - 虚继承要求Table类继承自Data类,不符合既定继承关系定义。
解决方案
核心思路是通过union内存重叠,让TableDerived中DataDerived的DataBase基类子对象与TableBase的data共享同一内存空间,同时满足所有限制条件:
#include <utility> struct DataBase{ int i{}; }; struct DataDerived : DataBase{ int j{}; DataDerived(DataBase&& d):DataBase(std::move(d)){} // 保留独立构造能力 DataDerived() = default; }; struct TableBase{ DataBase data; // 保留独立构造能力 TableBase() = default; TableBase(DataBase db) : data(std::move(db)) {} }; struct TableDerived { // union让TableBase与DataDerived共享前sizeof(DataBase)的内存 union { TableBase base; DataDerived data; }; // 构造函数:先初始化TableBase的data,再复用该内存构造DataDerived TableDerived(DataBase db) { // 初始化TableBase的data成员 new (&base.data) DataBase(std::move(db)); // 在base的内存位置构造DataDerived,复用已初始化的DataBase new (&data) DataDerived(std::move(base.data)); } // 保留独立构造能力 TableDerived() { // 默认构造DataDerived,同时初始化其基类DataBase(即base.data) new (&data) DataDerived(); } // 手动调用析构函数,union成员不会自动析构 ~TableDerived() { data.~DataDerived(); } // 禁用拷贝/移动构造避免内存管理问题(可按需实现) TableDerived(const TableDerived&) = delete; TableDerived& operator=(const TableDerived&) = delete; TableDerived(TableDerived&&) = delete; TableDerived& operator=(TableDerived&&) = delete; };
方案说明
- 内存重叠实现:
union确保TableBase::data与DataDerived的DataBase基类子对象占用同一内存地址,完全满足“同一物理实例”的要求; - 无动态内存分配:所有对象均分配在栈或对象自身内存中,符合限制条件;
- 类的独立性:四个类都保留默认构造能力,可单独实例化使用;
- 构造安全:通过placement new手动控制对象构造顺序,确保
DataDerived正确复用TableBase的DataBase实例。
内容的提问来源于stack exchange,提问作者mhawth36
相关产品推荐
相关产品推荐

