C++14(VS2015)protected继承下shared_ptr转换失败问题求助
在C++14(VS2015)环境中,使用protected继承结合std::shared_ptr时出现编译错误,提示“no suitable user defined conversion”,但改为public继承时代码可正常编译。测试代码如下:
class ioptionpricer { public: virtual std::shared_ptr<ioptionpricer> clone() const = 0; virtual void doSomething() const = 0; virtual ~ioptionpricer() = default; }; class optionpricer : protected ioptionpricer { public: std::shared_ptr<ioptionpricer> clone() const { return std::make_shared<optionpricer>(*this); } };
原因解析
核心问题出在protected继承的访问权限限制:
- 当
optionpricer以protected方式继承ioptionpricer时,optionpricer对象向ioptionpricer类型的转换,仅允许在optionpricer类的内部、其子类或友元中进行。 std::make_shared<optionpricer>(*this)会生成一个std::shared_ptr<optionpricer>,而我们需要将它转换为std::shared_ptr<ioptionpricer>返回。这个转换需要把底层的optionpricer*转为ioptionpricer*,但std::shared_ptr的构造函数不属于optionpricer的内部、子类或友元范畴,因此无法获取这个转换的权限,编译器就会抛出转换失败的错误。- 改为public继承后,
optionpricer到ioptionpricer的转换是公开的,任何上下文都能执行这个转换,因此std::shared_ptr<optionpricer>可以自动转换为std::shared_ptr<ioptionpricer>,代码正常编译。
解决方法
如果要保留protected继承,可以在clone函数内部显式完成转换,比如:
std::shared_ptr<ioptionpricer> clone() const { // 方式1:直接用static_cast完成转换 return std::shared_ptr<ioptionpricer>(static_cast<ioptionpricer*>(new optionpricer(*this))); // 方式2:用static_pointer_cast转换shared_ptr // return std::static_pointer_cast<ioptionpricer>(std::make_shared<optionpricer>(*this)); }
这两种方式都是在optionpricer的成员函数内部执行转换,这里有权限完成optionpricer*到ioptionpricer*的类型转换,因此可以通过编译。
内容的提问来源于stack exchange,提问作者Justin Mathew
相关产品推荐
相关产品推荐

