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

如何在C++中深拷贝含指针类型的std::variant?

实现std::variant中指针元素的深拷贝(含非variant替代方案)

一、基于std::variant的优化实现

不用逐个判断类型,借助std::visit可以统一处理variant的所有备选类型,自动匹配对应类型的深拷贝逻辑,代码更简洁且扩展性强。

代码示例(裸指针版本)

#include <variant>
#include <vector>

class a {
public:
    int* placeholder; 
    a() : placeholder(new int(0)) {}
    a(const a& _copy) : placeholder(new int(*_copy.placeholder)) {} // 深拷贝实现
    ~a() { delete placeholder; }
    // 禁用移动语义避免浅拷贝风险
    a(a&&) = delete;
    a& operator=(const a&) = delete;
    a& operator=(a&&) = delete;
}; 

class b {
public:
    int* placeholder; 
    b() : placeholder(new int(0)) {}
    b(const b& _copy) : placeholder(new int(*_copy.placeholder)) {}
    ~b() { delete placeholder; }
    b(b&&) = delete;
    b& operator=(const b&) = delete;
    b& operator=(b&&) = delete;
};

int main() {
    std::vector<std::variant<a*, b*>> instances;
    // 初始化示例
    instances.push_back(new a());
    instances.push_back(new b());

    // 深拷贝第一个元素到vector末尾
    std::visit([&](auto* ptr) {
        // 模板自动推导当前类型,创建深拷贝对象后加入vector
        using Type = std::decay_t<decltype(*ptr)>;
        instances.push_back(new Type(*ptr));
    }, instances[0]);
}

更安全的智能指针版本

用std::unique_ptr替代裸指针,避免手动管理内存的泄漏风险:

#include <variant>
#include <vector>
#include <memory>

// 类定义同上方a、b...

int main() {
    std::vector<std::variant<std::unique_ptr<a>, std::unique_ptr<b>>> instances;
    // 初始化
    instances.emplace_back(std::make_unique<a>());
    instances.emplace_back(std::make_unique<b>());

    // 深拷贝第一个元素
    std::visit([&](const auto& unique_ptr) {
        using Type = std::decay_t<decltype(*unique_ptr)>;
        instances.emplace_back(std::make_unique<T>(*unique_ptr));
    }, instances[0]);
}

二、非std::variant的替代方案:多态基类+Clone模式

如果可以放弃variant,用多态设计更符合面向对象逻辑,尤其当a、b具备相似行为时,扩展性和可读性更强。

代码示例

#include <vector>
#include <memory>

// 抽象基类,定义统一接口
class Base {
public:
    virtual ~Base() = default;
    // 纯虚clone方法,子类实现自身深拷贝逻辑
    virtual std::unique_ptr<Base> clone() const = 0;
};

class a : public Base {
public:
    int* placeholder; 
    a() : placeholder(new int(0)) {}
    a(const a& _copy) : placeholder(new int(*_copy.placeholder)) {}
    ~a() { delete placeholder; }

    std::unique_ptr<Base> clone() const override {
        return std::make_unique<a>(*this);
    }
}; 

class b : public Base {
public:
    int* placeholder; 
    b() : placeholder(new int(0)) {}
    b(const b& _copy) : placeholder(new int(*_copy.placeholder)) {}
    ~b() { delete placeholder; }

    std::unique_ptr<Base> clone() const override {
        return std::make_unique<b>(*this);
    }
};

int main() {
    std::vector<std::unique_ptr<Base>> instances;
    instances.emplace_back(std::make_unique<a>());
    instances.emplace_back(std::make_unique<b>());

    // 深拷贝第一个元素到末尾,无需关心具体类型
    instances.push_back(instances[0]->clone());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:48:19