【问题标题】:C++: Storing derived class's instance pointers in STL container of containersC++:将派生类的实例指针存储在容器的 STL 容器中
【发布时间】:2021-06-18 10:38:14
【问题描述】:

我阅读了Passing shared_ptr<Derived> as shared_ptr<Base>,但这并没有回答我的问题。

假设我们有

class Base
{
};

class Derived : public Base
{
};

我想创建以下容器:std::map&lt;int, std::shared_ptr&lt;std::unordered_map&lt;std::string, std::shared_ptr&lt;Base&gt;&gt;&gt;&gt; _channels;

我需要将实例添加为类型为 std::shared_ptr&lt;std::unordered_map&lt;std::string, std::shared_ptr&lt;Base&gt;&gt;&gt;std::shared_ptr&lt;std::unordered_map&lt;std::string, std::shared_ptr&lt;Derived&gt;&gt;&gt; 的值。

很遗憾,我无法添加 Derived 类型的实例,但 Base 类型的实例很好。

完整代码:

#include <iostream>
#include <string>
#include <map>
#include <unordered_map>
#include <memory>
#include <utility>

class Base
{
};

class Derived : public Base
{
};

int main()
{
// works fine
/*
    std::map<int, std::shared_ptr<Base>> _channels2;
    _channels2.emplace(std::pair<int, std::shared_ptr<Derived>>(3, std::make_shared<Derived>()));
    std::cout << "_channels2.size() = " << _channels2.size() << std::endl;
*/

// fails to compile
    std::map<int, std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Base>>>> _channels;
    _channels.emplace(std::pair<int, std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Derived>>>>(2, std::make_shared<std::unordered_map<std::string, std::shared_ptr<Derived>>>()));
    std::cout << "_channels.size() = " << _channels.size() << std::endl;

    return 0;
}

我正在使用 C++14。

  1. 我理解得很好,所以它无法编译的原因是因为std::shared_ptr&lt;std::unordered_map&lt;std::string, std::shared_ptr&lt;Derived&gt;&gt;&gt; 不是std::shared_ptr&lt;std::unordered_map&lt;std::string, std::shared_ptr&lt;Base&gt;&gt;&gt; 的子类型?所以在这种情况下多态是不可用的。

  2. 您有什么解决方法可以建议吗?

谢谢。

【问题讨论】:

  • 乘坐两辆公共汽车:一辆只有父亲,第二辆只有他们的孩子。第一辆公共汽车必须是第二辆公共汽车的父亲吗?
  • 嗯,是的,我的主要问题是是否存在像 Java 中的通配符扩展参数这样的语言特性。

标签: c++ inheritance stl c++14 liskov-substitution-principle


【解决方案1】:

考虑到这可行,您可以尝试一些方法:

std::map<std::string, std::shared_ptr<Derived>> derived_map;
std::map<std::string, std::shared_ptr<Base>> base_map(derived_map.begin(), derived_map.end());

因此你可以写:

std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Derived>>> derived_map;
auto base_map = std::make_shared<std::unordered_map<std::string, std::shared_ptr<Base>>>(derived_map->begin(), derived_map->end());

依此类推...缺点是只有基础和派生是“共享的”,地图是重复的。

【讨论】:

  • 感谢您的回答,不幸的是迭代很少适合我的课程。
  • 没有真正的迭代,我这么说是因为你使用了相当复杂的结构,所以你需要一个接一个地构建它们
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多