unique_ptr移动语义下虚方法未被正确覆写的问题
问题排查与解决方案:Adapter未正确覆写Target虚方法
问题根源
你遇到的问题和unique_ptr所有权转移无关,核心是Adapter类的getResponse方法签名与基类Target的不匹配,导致没有真正覆写虚函数:
- Target的
getResponse是非const成员函数:virtual std::string getResponse () - Adapter的
getResponse是const成员函数:std::string getResponse () const
这两个函数签名不同,属于重载而非覆写。当通过unique_ptr<Target>调用getResponse时,编译器只会匹配基类的非const版本,所以始终输出"simple response"。
解决方案
有两种可行的修正方式,选其一即可:
方式1:移除Adapter方法的const修饰
将Adapter中的getResponse方法的const去掉,让签名和基类完全一致,同时建议加上override关键字(C++11及以上支持),强制编译器检查是否正确覆写虚函数,避免类似问题:
class Adapter:public Target { unique_ptr < Adaptee > m_adaptee; public: Adapter (unique_ptr < Adaptee > adaptee ) : m_adaptee (std::move (adaptee)) { } std::string getResponse () override // 移除const,添加override { return m_adaptee->getSpecialRequest (); } };
方式2:给基类Target的方法添加const修饰
如果业务逻辑允许getResponse是const方法,也可以修改基类的签名,保持和子类一致,同样加上override:
class Target { public: virtual std::string getResponse () const // 添加const { return "simple response"; } }; class Adapter:public Target { unique_ptr < Adaptee > m_adaptee; public: Adapter (unique_ptr < Adaptee > adaptee ) : m_adaptee (std::move (adaptee)) { } std::string getResponse () const override // 添加override { return m_adaptee->getSpecialRequest (); } };
修正后的完整代码示例
以方式1为例,完整代码如下:
#include <iostream> #include <memory> using namespace std; class Target { public: virtual std::string getResponse () { return "simple response"; } }; class Adaptee { public: std::string getSpecialRequest () { return "Special response"; } }; class Adapter:public Target { unique_ptr < Adaptee > m_adaptee; public: Adapter (unique_ptr < Adaptee > adaptee ) : m_adaptee (std::move (adaptee)) { } std::string getResponse () override { return m_adaptee->getSpecialRequest (); } }; class client { unique_ptr < Target > m_target; public: client ( unique_ptr < Target > target) { m_target = std::move (target); std::cout << m_target->getResponse () << endl; // 添加换行,输出更清晰 } }; int main () { unique_ptr <Target> oj = make_unique <Target> (); unique_ptr <Adaptee > oj1 = make_unique <Adaptee> (); unique_ptr < Target > oj2 = make_unique<Adapter> (std::move(oj1)); client instance (std::move (oj)); client oj3 (std::move (oj2)); return 0; }
运行后会输出预期结果:
simple response special response
内容的提问来源于stack exchange,提问作者user2997518
相关产品推荐
相关产品推荐

