【发布时间】:2020-01-02 03:34:05
【问题描述】:
是否可以在初始化列表中向上转换共享指针对象引用?
我有两个具有匹配派生类的类层次结构。假设我有一个Base 类,它派生到Foo 和Bar 类。然后我有一个带有ProxyBase 类的单独层次结构,然后(为了匹配另一个层次结构)有FooProxy 和BarProxy。
ProxyBase 类存储shared_ptr<Base>。创建ProxyFoo 时需要std::shared_ptr<Foo>&,创建ProxyBar 时需要std::shared_ptr<Bar>&。
我可以通过两种方式完成这项工作:
- 不要使用对
std::shared_ptr<*>对象的引用。 - 使用
std::shared_ptr<Base>& obj作为ProxyFoo和ProxyBar构造函数的输入。这需要在构造函数中进行向下转换(我想避免)(因为我想要Foo和Bar特定属性),而且它使合同/API 比它应该允许的更多。
但我想知道这是否可以通过引用来完成。
我认为我知道问题出在哪里:当我删除引用时它起作用了,我认为这是因为从技术上不允许“强制转换”shared_ptr<X>;它只能通过创建派生/基本类型的新 shared_ptr 对象来“转换”。当使用引用时,人们会尝试将一个 shared_ptr 对象实际转换为另一个不允许的对象。这是正确的吗?
最初我认为这是std::static_pointer_cast 会有所帮助的情况之一,但如果我的假设是正确的,那也无济于事。
独立示例:
#include <memory>
class Base { };
class Foo : public Base
{
private:
int val_;
public:
Foo(int val) : val_(val) { }
};
class ProxyBase
{
protected:
std::shared_ptr<Base> obj_;
ProxyBase(std::shared_ptr<Base>& obj) : obj_(obj) { }
};
class FooProxy : public ProxyBase
{
public:
FooProxy(std::shared_ptr<Foo>& fobj) : ProxyBase(fobj) { }
};
int main()
{
auto f = std::make_shared<Foo>(42);
auto fp = std::make_shared<FooProxy>(f);
}
所以我的问题归结为:是否可以在不删除引用的情况下在上面的(当前非功能性)代码中做我想做的事情,同时保留 Foo 和 Bar 特定的构造函数FooProxy 和 BarProxy?
【问题讨论】:
-
为什么有(非 const)参考?
-
@Jarod42 因为纯粹的无知。 :) 我曾想象过 const 会使 shared_ptr 对象完全不可变(即不能 clone:able(用 Rust 说话)),但 Barry 的回答清楚地表明我在 const 和 shared_ptr 方面存在严重的知识差距。
-
智能ptr语义遵循ptr语义!
标签: c++ inheritance casting c++17 shared-ptr