C++ C+中不同派生类的有效容器+;

C++ C+中不同派生类的有效容器+;,c++,memory,vector,containers,allocation,C++,Memory,Vector,Containers,Allocation,在编写游戏时,我通常将所有游戏对象存储在一个具有初始化和固定大小的std::vector中。最近,我觉得需要在游戏对象类之间进行一些继承 让我们假设我有40个来自我的类敌人的类。如果我想将这些类的对象/实例存储在向量中,我只能选择将它们存储为向量,对吗?所以唯一被连续分配的是指针,对吗?所以当需要取消引用时,我仍然会有很多缓存未命中,对吗 有没有什么“最佳实践”方法可以将派生类存储在指定的内存中,这样循环它们所需的时间最短?Boost刚刚接受了一个库,正是出于这个目的:。特别是,您正在寻找 在内

在编写游戏时,我通常将所有游戏对象存储在一个具有初始化和固定大小的std::vector中。最近,我觉得需要在游戏对象类之间进行一些继承

让我们假设我有40个来自我的类敌人的类。如果我想将这些类的对象/实例存储在向量中,我只能选择将它们存储为向量,对吗?所以唯一被连续分配的是指针,对吗?所以当需要取消引用时,我仍然会有很多缓存未命中,对吗


有没有什么“最佳实践”方法可以将派生类存储在指定的内存中,这样循环它们所需的时间最短?

Boost刚刚接受了一个库,正是出于这个目的:。特别是,您正在寻找

在内部,它使用许多向量,每个(派生)类型一个,同时提供接近标准容器的接口

作者提供了一些设计背景,并与其他解决方案进行了比较,如
unique\u ptr
向量。优点有两个:第一,通过不使用指针和每个元素的动态内存分配,可以获得更好的内存局部性;第二,将相同类型的元素分组在一起,并为虚拟成员函数提供指令缓存

这个怎么样

struct alignas(...) Base {};
struct Derived1 : Base {};
struct Derived2 : Base {};

int main()
{
    std::vector<Base> v(2);
    new (&v[0]) Derived1();
    new (&v[1]) Derived2();
    return 0;
}
其中,
VisitPackage
可以是这样的:

int main()
{
    std::vector<std::variant<Derived1, Derived2>> v;
    v.emplace_back(Derived1());
    v.emplace_back(Derived2());

    for (const auto& e : v)
        std::visit(VisitPackage(), e);

    return 0;
}
struct VisitPackage
{
    void operator()(const Derived1&) { std::cout << "Derived 1.\n"; }
    void operator()(const Derived2&) { std::cout << "Derived 2.\n"; }
};
struct VisitPackage
{

void运算符()(const Derived1&){std::我想他是在谈论类实例。这对我来说似乎很清楚。我指的是那些类的对象。实例。在运行时创建并分配的东西。在向量中使用指向基类的指针,或者如果它更合适的话,使用某种智能指针。我想将它们存储在向量中正是你所看到的ng for.Vectors似乎是c++用于迭代和存储的最佳实践工具。因为它们是指针,所以它与向量相同,所以这也很好。有几种方法,但它们在技术上都非常复杂。我强烈建议您从
向量和基准测试开始。如果您确实需要走这条路,这是最简单的/对于如此大量的派生类,最可行的方法是使用自定义分配器,以确保所有的敌人都在一个连续的内存块中构造。您仍然可以使用一个唯一的ptr向量和一个自定义的deleter,并使用一些其他函数,而不是
make_unique
。这样做的唯一目的是你必须手动管理大小和对齐,而且你可能也过度对齐了,因为
alignas
从来都不是用来管理分配大小,只是用来管理对象在内存中的位置。基本上,你所做的是一个拼凑在一起的
std::vector
:)真的lol。但是std::visit需要涵盖所有情况。无论如何,我同意您对alignas的评论。如果您对相同类型的元素进行分组,是否有更好的效果还不清楚。在许多情况下,在时间上紧密分配的对象之间存在着很强的关系。在其他情况下,重要的是将派生类型的所有对象存储在一起,而不需要分组。然后cts可能永远存在,并且全部一起出售-然后,竞技场将表现得更好。与大多数事情一样,当性能重要时,您必须对其进行分析,
poly_collection
可能会表现出最好的替代方案,或者不太好。