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
相关产品推荐
相关产品推荐

