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

C++中成员对象存储方式不同(栈vs堆)时如何共享类函数?

消除类A和类B的代码冗余方案

针对你描述的场景,两个类拥有完全相同的操作逻辑,但数据存储方式不同(栈数组 vs 外部指针),可以通过以下两种C++常用方式消除代码冗余:

方案一:使用CRTP(奇异递归模板模式)

将公共操作逻辑抽离到模板基类中,利用CRTP让子类提供数据成员的访问,避免重复编写函数:

// 模板基类,封装所有公共操作
template <typename Derived>
class CommonOperations {
public:
    int do_stuff() {
        // 访问子类的numbers成员
        auto& data = static_cast<Derived*>(this)->numbers;
        return data[0] + data[1];
    }

    // 在这里添加其他20个公共函数,逻辑完全复用
    // 例如:
    // int another_operation() { ... }
};

// 类A:栈上存储数据
class A : public CommonOperations<A> {
private:
    int numbers[200];
public:
    A() = default;
    // 允许基类访问私有成员numbers
    friend class CommonOperations<A>;
};

// 类B:外部传入数据指针
class B : public CommonOperations<B> {
private:
    int* numbers;
public:
    B(int* num) : numbers(num) {}
    friend class CommonOperations<B>;
};

这种方式的核心是让基类通过子类的类型来访问其数据成员,所有公共逻辑只需编写一次,子类仅需定义自身的存储方式和构造函数。

方案二:使用策略模式分离存储与操作

将存储逻辑封装为独立的策略类,操作逻辑作为模板类复用不同的存储策略:

// 栈存储策略
struct StackStorage {
    int numbers[200];
    // 统一数据访问接口
    int* get_data() { return numbers; }
    const int* get_data() const { return numbers; }
};

// 指针存储策略
struct PointerStorage {
    int* numbers;
    PointerStorage(int* num) : numbers(num) {}
    int* get_data() { return numbers; }
    const int* get_data() const { return numbers; }
};

// 操作模板类,依赖存储策略的统一接口
template <typename StoragePolicy>
class Operations : public StoragePolicy {
public:
    // 继承存储策略的构造函数
    using StoragePolicy::StoragePolicy;

    int do_stuff() {
        auto* data = this->get_data();
        return data[0] + data[1];
    }

    // 添加其他公共操作函数
};

// 定义类A和类B
using A = Operations<StackStorage>;
using B = Operations<PointerStorage>;

这种方式将存储和操作完全解耦,操作逻辑不依赖具体的存储方式,只需依赖统一的get_data接口,后续若新增其他存储类型,只需添加对应的策略类即可。

两种方案都能彻底消除重复代码,你可以根据实际场景的复杂度选择更适配的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:07:09