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

C++派生类从*this获取shared_ptr的歧义问题及解决方法

解决多重继承std::enable_shared_from_this导致的歧义问题

你遇到的错误是因为BBB同时继承了AAA(间接继承std::enable_shared_from_this<AAA>)和std::enable_shared_from_this<BBB>,两个基类都提供了shared_from_this成员函数,编译器无法确定调用哪个版本,因此出现歧义。下面给出两种可行的解决方案:

方案一:明确指定要调用的shared_from_this版本

在派生类中直接限定调用对应模板版本的shared_from_this,避免编译器的歧义查找:

#include <memory>

struct AAA : std::enable_shared_from_this<AAA>
{
    auto getA() -> std::shared_ptr<AAA> { return this->shared_from_this(); }
};

struct BBB : AAA, std::enable_shared_from_this<BBB>
{
    auto getB() -> std::shared_ptr<BBB> { 
        // 明确调用BBB对应的enable_shared_from_this版本
        return std::enable_shared_from_this<BBB>::shared_from_this(); 
    }
};

这种方法简单直接,但本质上仍存在两个enable_shared_from_this实例,虽能解决编译问题,但不够优雅。

方案二:避免多重继承enable_shared_from_this(推荐)

让派生类不再单独继承std::enable_shared_from_this,而是通过基类的shared_from_this获取指针后,用std::static_pointer_cast转换为派生类的shared_ptr,从根源上消除歧义:

#include <memory>
#include <functional>

struct AAA : std::enable_shared_from_this<AAA>
{
    auto set_attrZ(int val) -> std::shared_ptr<AAA> {
        // 实现属性设置逻辑
        return shared_from_this();
    }
    auto set_attrK(int val) -> std::shared_ptr<AAA> {
        // 实现属性设置逻辑
        return shared_from_this();
    }
};

struct BBB : AAA
{
    auto set_attrA(int val) -> std::shared_ptr<BBB> {
        // 实现属性设置逻辑
        return std::static_pointer_cast<BBB>(shared_from_this());
    }
    auto set_attrB(int val) -> std::shared_ptr<BBB> {
        // 实现属性设置逻辑
        return std::static_pointer_cast<BBB>(shared_from_this());
    }
    auto set_callback(std::function<void()> cb) -> std::shared_ptr<BBB> {
        // 实现回调设置逻辑
        return std::static_pointer_cast<BBB>(shared_from_this());
    }
    auto do_some_work() -> std::shared_ptr<BBB> {
        // 实现工作逻辑
        return std::static_pointer_cast<BBB>(shared_from_this());
    }
};

这种方案完全满足你的链式调用需求:

// 链式调用示例
auto a = std::make_shared<AAA>()
   -> set_attrZ(1)
   -> set_attrK(2);

auto b = std::make_shared<BBB>()
   -> set_attrA(1)
   -> set_attrB(2)
   -> set_callback([](){ /* ... */ });

std::make_shared<BBB>()
   -> set_attrA(1)
   -> set_attrB(2)
   -> set_callback([](){ /* ... */ })
   -> do_some_work();

原理说明

当你用std::make_shared<BBB>()创建实例时,std::enable_shared_from_this<AAA>内部的weak_ptr会被正确关联到这个shared_ptr的控制块。调用shared_from_this()会返回std::shared_ptr<AAA>,通过std::static_pointer_cast转换为std::shared_ptr<BBB>是安全的——因为当前实例确实是BBB类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:03:17