我有许多不相关的类型,它们都通过重载的自由函数(ad hoc多态)支持相同的操作:
struct A {};
void use(int x) { std::cout << "int = " << x << std::endl; }
void use(const std::string& x) { std::cout << "string = " << x << std::endl; }
void use(const A&) { std::cout << "class A" << std::endl; }
正如问题的标题所暗示的那样,我希望将这些类型的实例存储在异构容器中,这样use()无论它们具体是什么类型,我都可以使用它们.容器必须具有值语义(即两个容器之间的赋值复制数据,它不共享它).
std::vector<???> items;
items.emplace_back(3);
items.emplace_back(std::string{ "hello" });
items.emplace_back(A{});
for (const auto& item: items)
    use(item);
// or better yet
use(items);
当然,这必须是完全可扩展的.考虑一个带有a的库API vector<???>,以及将自己的类型添加到已知类型的客户端代码.
通常的解决方案是将(智能)指针存储到(抽象)接口(例如vector<unique_ptr<IUsable>>),但这有许多缺点 - 从我的头脑:
这是一个相关帖子的续集,它询问了永恒的问题:
我可以在C++中使用具有值语义的多态容器吗?
问题稍有不正确.应该更像是:
我可以使用按值存储的基类型的STL容器,其中元素表现出多态行为吗?
如果你用C++问这个问题,答案是"不".在某些时候,您将切片按值存储的对象.
现在我再次提出这个问题,但严格来说是C++ 11.通过对语言和标准库的更改,现在可以在STL容器中按值存储多态对象吗?
我很清楚在容器中存储智能指针到基类的可能性 - 这不是我正在寻找的,因为我试图在不使用的情况下在堆栈上构造对象new.
考虑你是否(从链接的帖子)作为基本的C++示例:
#include <iostream>
using namespace std;
class Parent
{
    public:
        Parent() : parent_mem(1) {}
        virtual void write() { cout << "Parent: " << parent_mem << endl; }
        int parent_mem;
};
class Child : public Parent
{
    public:
        Child() : child_mem(2) { parent_mem = 2; }
        void write() { cout << "Child: " << parent_mem << ", " << child_mem << endl; }
        int child_mem;
}; …所以我正在研究一个基于文本的RPG,我遇到了一个问题.我目前正在从角色的库存中装备武器.我试图这样做,以便我的程序可以判断他们想要装备的物品是否属于等级Weapon.这是相关代码的剪辑:
 Item tempChosenWeapon = myInventory.chooseItem();
cout << tempChosenWeapon.getName() << endl;
Item *chosenWeapon = &tempChosenWeapon;
cout << chosenWeapon->getName() << endl;//THE CODE WORKS UP TO HERE
Weapon *maybeWeapon = dynamic_cast<Weapon*>(chosenWeapon);
cout << maybeWeapon->getName() << endl;
现在,Weapon是一个子类Item,这就是为什么我使用动态强制转换 - 尝试更改chosenWeapon(类型)Item,Weapon以便比较两个类.(我正在使用这些cout<<或测试是否从这些对象调用函数).
我的程序编译,一切运行正常,直到我们来到maybeWeapon->getName()程序崩溃.我已经研究了很多,但我只是不明白我做错了什么.任何答案或替代建议非常感谢!谢谢!
c++ polymorphism software-design game-development game-engine