c++ - 在初始化列表中转换 shared_ptr

标签 c++ inheritance casting c++17 shared-ptr

是否可以在初始化列表中向上转换共享指针对象引用?

我有两个具有匹配派生类的类层次结构。假设我有一个 Base派生到 Foo 的类和一个 Bar类(class)。然后我有一个单独的层次结构,带有 ProxyBase类,然后(为了匹配其他层次结构)有 FooProxyBarProxy .

ProxyBase类存储一个shared_ptr<Base> .当 ProxyFoo创建它需要一个 std::shared_ptr<Foo>& , 当 ProxyBar创建它需要一个 std::shared_ptr<Bar>& .

我可以通过两种方式完成这项工作:

  • 不要引用 std::shared_ptr<*>对象。
  • 使用std::shared_ptr<Base>& obj作为 ProxyFoo 的输入和 ProxyBar构造函数。这需要在构造函数中进行向下转换(我想避免)(因为我想要 FooBar 特定属性),而且它使契约(Contract)/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);
}

所以我的问题归结为:是否可以在不删除引用的情况下在上面的(当前非功能性)代码中执行我正在尝试执行的操作,同时保留 FooBar特定构造函数 FooProxyBarProxy

最佳答案

A shared_ptr<Derived>可以转换shared_ptr<Base> , 但它不是 shared_ptr<Base> .

换句话说,这个编译:

std::shared_ptr<Derived> pd;
std::shared_ptr<Base> pb = pd;

但这不是:

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

但这确实如此,因为 const 引用可以绑定(bind)到临时对象,这将隐式执行转换:

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

问题是您在构造函数中使用了非常量左值引用。您应该采用 const 左值引用或仅按值采用它们。

关于c++ - 在初始化列表中转换 shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57700321/

相关文章:

c++ - 使用 gprof 和 boost

c++ - APP和DLL依赖一些文件: on which directory?

ios - Swift 3 (SpriteKit) 从自定义类中将子项添加到 GameScene

c++ - 函数参数中的空指针和强制转换

c++ - CPP、WinAPI - WM_CREATE 从 lParam 获取 CREATESTRUCT* 的正确方法

c++ - 可移植内存搜索功能的返回类型

用于信号处理的 C++ 库

c++ - 错误C2011 : 'class type redefinition - Basic Inheritance

Java:父类(super class)中私有(private)变量的初始化

c++ - boost::以下代码的任意替换