C++ 在初始值设定项列表中强制转换共享\u ptr

C++ 在初始值设定项列表中强制转换共享\u ptr,c++,inheritance,casting,c++17,shared-ptr,C++,Inheritance,Casting,C++17,Shared Ptr,是否可以在初始值设定项列表中向上强制转换共享指针对象引用 我有两个具有匹配派生类的类层次结构。假设我有一个Base类,它派生为Foo和Bar类。然后我用一个ProxyBase类创建了一个单独的层次结构,然后(为了匹配其他层次结构)有FooProxy和BarProxy ProxyBase类存储一个shared\u ptr。创建ProxyFoo时需要std::shared\u ptr&,创建ProxyBar时需要std::shared\u ptr& 我可以通过两种方式实现这一目标: 不要使用对st

是否可以在初始值设定项列表中向上强制转换共享指针对象引用

我有两个具有匹配派生类的类层次结构。假设我有一个
Base
类,它派生为
Foo
Bar
类。然后我用一个
ProxyBase
类创建了一个单独的层次结构,然后(为了匹配其他层次结构)有
FooProxy
BarProxy

ProxyBase
类存储一个
shared\u ptr
。创建
ProxyFoo
时需要
std::shared\u ptr&
,创建
ProxyBar
时需要
std::shared\u ptr&

我可以通过两种方式实现这一目标:

  • 不要使用对
    std::shared_ptr
    对象的引用
  • 使用
    std::shared_ptr&obj
    作为
    ProxyFoo
    ProxyBar
    构造函数的输入。这需要在构造函数中进行向下转换(我希望避免这种情况)(因为我需要
    Foo
    Bar
    特定属性),此外,它使契约/API比它应该允许的更多
但我想知道这是否可以通过参考来实现

我想我知道问题是什么:当我删除引用时,它是有效的,我想这是因为“铸造”一个
shared\u ptr
在技术上是不允许的;它只能通过创建派生/基本类型的新
共享\u ptr
对象来“浇铸”。使用引用时,试图将一个
共享的\u ptr
对象实际强制转换为另一个不允许的对象。这是正确的吗

起初,我认为这是其中一种情况,
std::static\u pointer\u 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类:公共基础
{
私人:
int val_;
公众:
Foo(int-val):val_(val){}
};
类ProxyBase
{
受保护的:
std::共享对象;
ProxyBase(std::shared_ptr&obj):obj_j(obj){}
};
类FooProxy:publicproxybase
{
公众:
FooProxy(std::shared_ptr&fobj):ProxyBase(fobj){}
};
int main()
{
自动f=std::使_共享(42);
自动fp=std::使_共享(f);
}
因此,我的问题归结为:是否有可能做我在(目前非功能性)中尝试做的事情在不删除引用的情况下对上面的代码进行编码,同时保留
Foo
Bar
特定构造函数,以
FooProxy
BarProxy

A
shared\u ptr
可以转换为
shared\u ptr
,但它不是
shared\u ptr

换言之,这包括:

std::shared_ptr<Derived> pd;
std::shared_ptr<Base> pb = pd;
std::shared_ptr pd;
std::shared_ptr pb=pd;
但这并不是:

std::shared_ptr<Base>& pb = pd;
std::shared_ptr&pb=pd;
但这样做是因为常量引用可以绑定到临时变量,这将隐式执行转换:

std::shared_ptr<Base> const& pb = pd;
std::shared_ptr const&pb=pd;

问题是您在构造函数中使用非常量左值引用。你要么接受常量左值引用,要么只接受它们的值。

为什么你有(非常量)引用?@Jarod42,因为纯粹的无知。:)我曾想象一个const会使共享的_ptr对象完全不可变(即不是clone:able(使用Rust-speak)),但Barry的回答清楚地表明,我对const和共享的_ptr存在严重的知识差距。智能的ptr语义遵循ptr语义!最肯定的是,它应该是通过价值,然后移动。