Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将分配器分配给字段-是否应将默认分配器创建为全局变量?_C++_Singleton_C++14_Allocator - Fatal编程技术网

C++ 将分配器分配给字段-是否应将默认分配器创建为全局变量?

C++ 将分配器分配给字段-是否应将默认分配器创建为全局变量?,c++,singleton,c++14,allocator,C++,Singleton,C++14,Allocator,我的游戏引擎有两个分配器:堆和堆栈 class GameEngine{public: Allocator* heap; //<-- a custom allocator class Allocator* stack; } 图如下:- 问题 如果car类增长,并且有很多字段需要分配器:- class Car{ MyArray<Car*> nearEnemyCache; //<-- need allocator class A{ }

我的游戏引擎有两个分配器:堆和堆栈

class GameEngine{public:
    Allocator* heap;  //<-- a custom allocator class
    Allocator* stack;
}
图如下:-

问题 如果
car
类增长,并且有很多字段需要分配器:-

class Car{
    MyArray<Car*> nearEnemyCache; //<-- need allocator
    class A{    };
    MyArray<A> as;  //<--- need allocator
    class B{}; 
    MyUnorderMap<B> bs; //<--- need allocator
};
等级车{

MyArray nearEnemyCache;//如果您无法想象存在多个堆栈/堆/引擎的情况,那么最好将其表示为单例

这也可以与模板化容器相匹配:如果您知道您的汽车只会使用堆分配,那么在nearEnemyCache附近有一个成员,如
MyArray;
将允许容器只访问相应的单例(并且将从您的“真实”逻辑中隐藏该部分,这样就不会再脏了)

模板
类MyArray
{
公众:
MyArray():分配程序(singleton::get())
{
}
void setAllocator(分配器*alloc)
{
_分配器=alloc;
}
私人:
分配器*\u分配器;
};
然后,如果您愿意,可以在运行时设置它,但如果您在编译时知道它,则不必这样做。
ChosenAtRuntimeAlloc
类在被要求分配时只会抛出一个异常(
“必须在运行时设置一个分配器,然后再分配!”


如果您始终知道容器将使用哪些分配器(即,您永远不必默认使用第二个模板参数)然后,您甚至可以从分配器中删除所有虚拟函数,而允许编译器内联所有这些函数。这基本上就是标准库容器的工作方式。

您推出自己的容器而不使用
std::
实用程序有什么原因吗?可以用于研究目的。@DeiDei在一些测试中说在游戏中,我发现我的略快于std:
。分配器真的是在运行时确定的吗?模板化容器(以及使用它们的类)在分配器类型上,避免每次分配中的虚拟函数调用似乎是明智的性能明智之举。而且,您仍然可以在运行时在工厂中在两者之间做出决定。此外,为什么不将分配器传递给类构造函数(然后将其作为[optional?]参数进一步传递给容器)?@Max Langhof:我知道在
nearEnemyCache
中总是使用堆分配器(而不是堆栈)。分配器的实例是在运行时确定的,不过……为了简单起见,我使用了虚拟函数。我以后可能会改为模板。谢谢……将分配器传递给
Car()
constructor=将脏代码移动到
Car
类。我的代码的总脏代码将保持不变。谢谢。我喜欢你的
singleton::get()
。它与中描述的类似。嗯,singleton/global似乎是管理分配器的最佳方式。
class CarFactory{
    GameEngine* gameEngine;
    Car* createCar(){
        Car* car=new Car();
        car->nearEnemyCache.setAllocator( gameEngine->heap );
        return car;
    }
};
class Car{
    MyArray<Car*> nearEnemyCache; //<-- need allocator
    class A{    };
    MyArray<A> as;  //<--- need allocator
    class B{}; 
    MyUnorderMap<B> bs; //<--- need allocator
};
Car* createCar(){
    Car* car=new Car();
    car->nearEnemyCache.setAllocator( gameEngine->heap );
    car->as.setAllocator( gameEngine->heap );
    car->bs.setAllocator( gameEngine->heap );   //<-- so dirty & tedious
    return car;
}
Allocator* defaultAllocator;
template<class T>MyArray{
    Allocator* allocator=defaultAllocator;
    //... other stuffs
}
int main(){
    //create "gameEngine"
    defaultAllocator=gameEngine->heap;
    // start game
}
GameEngine* defaultGameEngine;
template<class T> class MyArray{
    Allocator* allocator=defaultGameEngine->heap;
    //... other stuffs
}
int main(){
    //create "gameEngine"
    defaultGameEngine=gameEngine;
    // start game
}
template<class T, class DefaultAlloc = ChosenAtRuntimeAlloc>
class MyArray
{
public:
    MyArray() : _allocator(singleton<DefaultAlloc>::get())
    {
    }

    void setAllocator(Allocator* alloc)
    {
        _allocator = alloc;
    }

private:
    Allocator* _allocator;
};