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

C++模板类继承场景下两个派生类互相链接时类型转换失败问题

问题根因
  • 你遇到的类型转换错误本质是:模板类Param_B<T>会根据不同的模板参数T生成完全独立、无继承关系的实例类型,Param_B<Param_S>和Param_B<Param_M>是两个完全不同的类,无法直接互相转换。
  • 当前Param_B类内的_link成员类型是std::weak_ptr<Param_B>,这里的Param_B实际是当前实例化的Param_B<T>类型,自然不能接收另一个模板参数的Param_B子类指针。
解决方案

核心是新增一层非模板的公共抽象基类,让所有Param_B<T>的实例都继承自这个基类,再将_link的类型替换为公共基类的指针,同时把跨子类需要调用的公共接口定义在抽象基类中:

步骤1:定义公共抽象基类

class Param_Base {
public:
    virtual ~Param_Base() = default;
    // 定义跨子类需要调用的公共接口,比如修改定时器超时
    virtual void setTimerTimeout(size_t timer_idx, int time) = 0;
    virtual int getTimerTimeout(size_t timer_idx) const = 0;
};

步骤2:修改Param_B模板类继承自公共基类,实现虚接口

template <class T>
class Param_B : public Param_Base {
public:
    Param_B(){};
    ~Param_B() override = default;

    std::vector<std::shared_ptr<Timer<T>>>& getTimers(){
        return _timers;
    }
    void addTimer(std::shared_ptr<Timer<T>> _t){
        _timers.push_back(std::move(_t));
    }
    // 修改link类型为公共基类
    std::weak_ptr<Param_Base> getLink(){
            return _link;
    }
    void setLink(std::weak_ptr<Param_Base> link){
            _link = link;
    }

    // 实现抽象基类的接口
    void setTimerTimeout(size_t timer_idx, int time) override {
        if (timer_idx < _timers.size()) {
            _timers[timer_idx]->setTimeout(time);
        }
    }
    int getTimerTimeout(size_t timer_idx) const override {
        if (timer_idx < _timers.size()) {
            return _timers[timer_idx]->getTimeout();
        }
        return -1;
    }

private:
    std::weak_ptr<Param_Base> _link;
    std::vector<std::shared_ptr<Timer<T>>> _timers;
};

步骤3:补充Timer类的getTimeout接口

template <class T>
class Timer
{
public:
    Timer(){ timeout = 0; };
    ~Timer(){};
    int getTimeout() const { return timeout; } // 新增接口
    void setTimeout(const int time){    timeout = time; };
    std::weak_ptr<Functionn<T>>& getFunction(){ return _func; };
    std::weak_ptr<T> getParent(){   return _parent;};

private:
    int timeout;
    std::weak_ptr<T> _parent;
    std::weak_ptr<Functionn<T>> _func;
};

修改完成后,原来报错的setLink调用就可以正常执行了,后续如果要在Param_S中修改关联的Param_M的定时器超时,只需要调用:

// 示例:在Param_S的成员函数中修改关联Param_M的第0个定时器超时
if (auto link_sp = getLink().lock()) {
    link_sp->setTimerTimeout(0, 1000); // 超时设为1000ms
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:06:01