【问题标题】:How to cast a shared_ptr<vector<derived class>> to a shared_ptr<vector<base class>>>?如何将 shared_ptr<vector<derived class>> 转换为 shared_ptr<vector<base class>>>?
【发布时间】:2021-11-28 23:38:48
【问题描述】:

作为标题,我有一个奇怪的要求。 代码示例:

class Base{
}
class Derived: Base{
}

//I want cast that.
shared_ptr<vector<Derived*>>  ->   shared_ptr<vector<Base*>>

这是我的方式:

shared_ptr<vector<Derived*>> derived_vector_sp;

auto* base_vector_rawptr = (vector<Base*> *)derived_vector_sp.get();

shared_ptr<vector<Base*>> base_vector_sp = make_shared<<vector<Base*>>>(*base_vector_rawptr);

它有效。但是通过这种方式我创建了anthor向量。两个shared_ptr管理两个不同的vecotr。
那么有没有办法直接结束这个案子?比如:

//this way doesn't work.
shared_ptr<vector<Base*>> base_vector_sp = static_pointer_cast<vector<Base*>>(derived_vector_sp);

【问题讨论】:

  • 你不能。将Dog* 的向量视为Animal* 的向量意味着您可以向其添加Cat*
  • 您不能将vector&lt;ptr*&gt; 从一种ptr 类型转换为另一种类型。不支持。
  • 听起来像是 XY 问题。您应该解释为什么需要这样做,对于该问题可能有更好/不同的解决方案。

标签: c++ vector shared-ptr stdvector


【解决方案1】:

您不能将shared_ptr&lt;vector&lt;Derived*&gt;&gt; 转换为shared_ptr&lt;vector&lt;Base*&gt;&gt;,因为vector&lt;Derived*&gt;vector&lt;Base*&gt; 是彼此不相关的两种不同类型。

在这种情况下,DerivedBase 相互关联并不重要。您使用std::vector&lt;Derived*&gt;std::vector&lt;Base*&gt; 创建的类型是从模板化std::vector 的类中创建的,因此这里只涉及std::vector 类模板给出的继承。

但是通过这种方式我创建了另一个向量。而两个shared_ptr管理两个不同的向量。

您可以考虑在原来的 vector&lt;Derived*&gt; 容器上创建一个 view

【讨论】:

  • '你可以考虑在你的原始向量 容器上创建一个视图。'我不明白。“视图”是什么意思?
  • @Jevon54 创建一个可以保存std::vector&lt;Derived*&gt; 的类,但迭代器和访问将返回一个指向Base 的指针。但正如我在另一条评论中所说,这听起来像是一个 XY 问题。所以你应该在你的问题中解释你为什么需要它。你试图用它解决什么问题。
【解决方案2】:

cast 是不可能的,因为即使 Derived 继承 Basevector&lt;Derived*&gt;vector&lt;Base*&gt; 类也是完全独立的类,根本没有任何关系。

如果您想要 vector&lt;Derived*&gt; 中的 vector&lt;Base*&gt;,这是可能的,但您需要自己转换指针。你当然会得到一个单独的向量。

std::vector<Derived*> source;

// Don't use this, use the version below
auto result = std::vector<Base*>(source.size());
for (std::size_t idx = 0; idx < source.size(); ++idx) {
    result[idx] = source[idx];
}
return result;

或者在更惯用的 C++ 中,我们只需让构造函数完成这项工作:

auto result = std::vector<Base*>(begin(source), end(source));

随机旁注:

  • 演员:

    (vector<Base*> *)derived_vector_sp.get(); // don't do this!
    

    这是完全违法的。那个位置没有vector&lt;Base*&gt;,所以 试图使用一个是未定义的行为。它可能看起来有效,然后你 升级你的编译器,它就会崩溃。

  • 通常使用shared_ptr 是一种代码异味。它有一些很好的用例,但大多数时候你应该直接使用对象,或者unique_ptr

  • 特别是当我们谈论 std::vector 时,它本身已经是一组指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2010-11-24
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 2012-11-04
    相关资源
    最近更新 更多