c++ - 将分配器分配给字段 - 我应该将默认分配器创建为全局变量吗?

标签 c++ singleton c++14 allocator

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

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

今天,我想创建一个需要堆分配器的类Car

class Car{
    MyArray<Car*> nearEnemyCache; //<-- my custom storage, need allocator
};

因此,为了创建汽车实例,我从engine 获取堆分配器并将其分配给car

class CarFactory{
    GameEngine* gameEngine;
    Car* createCar(){
        Car* car=new Car();
        car->nearEnemyCache.setAllocator( gameEngine->heap );
        return car;
    }
};

这是图表:-

enter image description here

问题

如果 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;
}

我的糟糕解决方案

这两种解决方案都直接或间接地使用全局变量作为默认分配器
我认为使用全局变量通常是一种不好的做法。

1。全局默认分配器

在程序开始设置全局分配器并作为默认值使用 例如:-

Allocator* defaultAllocator;
template<class T>MyArray{
    Allocator* allocator=defaultAllocator;
    //... other stuffs
}
int main(){
    //create "gameEngine"
    defaultAllocator=gameEngine->heap;
    // start game
}

2。全局游戏引擎变量。

GameEngine* defaultGameEngine;
template<class T> class MyArray{
    Allocator* allocator=defaultGameEngine->heap;
    //... other stuffs
}
int main(){
    //create "gameEngine"
    defaultGameEngine=gameEngine;
    // start game
}

类似问题:-

最佳答案

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

这也可以与您的容器模板化相结合:如果您知道您的汽车将只使用堆分配,那么拥有像 MyArray<Car*, HeapAllocator> nearEnemyCache; 这样的成员将允许容器只访问相应的单例(并将从您的“真实”逻辑中隐藏该部分,因此不会再有脏东西)。

template<class T, class DefaultAlloc = ChosenAtRuntimeAlloc>
class MyArray
{
public:
    MyArray() : _allocator(singleton<DefaultAlloc>::get())
    {
    }

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

private:
    Allocator* _allocator;
};

如果你愿意,你可以在运行时设置它,但如果你在编译时知道它,就不必这样做。 ChosenAtRuntimeAlloc当被要求分配时,类只会抛出异常("Must set an allocator at runtime before allocating!")。

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

关于c++ - 将分配器分配给字段 - 我应该将默认分配器创建为全局变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50737816/

相关文章:

c++ - 读取RAW音频文件

c++ - 节能自旋环

java - 如何调用单例方法?

c++ - C++ 模板化代码的语法和语义是什么?

c++ - 如何避免 Helgrind 的误报?

c++ - std::vector<uint8_t> 在启用 C++11/14 时手动复制而不是调用 memcpy

c++ - 我怎么可能从一个还没有定义一些成员方法的类中创建一个实例呢? (C++)

c++ - FRAPS 替代方案 : Where to look and what for?

php - 实现 PHP 单例 : static class properties or static method variables?

ios - swift中静态函数和单例类的区别