gpt4 book ai didi

c++ - 在哪里实例化依赖于主类的类?

转载 作者:行者123 更新时间:2023-11-30 02:54:03 25 4
gpt4 key购买 nike

我目前正在使用 SFML 开发 2D 游戏引擎,从程序开始,但决定将其移至 OOP 从长远来看会更好。我了解 OOP 的概念,但是,我不确定应该在哪里定义其他类(ImageManager、Grid 等)的实例化

例如,我的Engine类依赖于ImageManager,而Engine中的很多函数依赖于ImageManager中的变量>。因此,我不能简单地在单个函数中声明和定义 ImageManager 类的实例,因为它在其他函数中不可用。

我所做的是:引擎.h:

class Engine
{
private:
sf::RenderWindow window;
grid (*gridArray)[SIZE];
...//more variables, removing for length
//Initializes the engine
bool Init(); //Main Game Loop
void MainLoop(); //Renders one frame
void RenderFrame(); //Processes user input
void ProcessInput(); //Updates all Engine internals
public:
Engine(int w, int h, int tileSize);
~Engine();
ImageManager * imageManager;
GridClass * gridClass;
...//removed some methods for length
};

基本上,您可以看到我在 header 中声明了两个类,ImageManagerGridClass。Engine.cpp 内部:

Engine::Engine(int w, int h, int tileSize)
{
imageManager = new ImageManager;
gridClass = new GridClass();
gridArray = new grid[SIZE][SIZE]();
masterArray = new unsigned char[MAP_SIZE][MAP_SIZE];
videoSize = sf::Vector2i(w, h);
this->tileSize = tileSize;
startX = startY = endX = endY = 0;
}

我正在定义类。我在构造函数中执行此操作,因为我不确定应该在哪里执行以符合良好做法。我一直遇到 imageManager 元素损坏的问题,所以我想知道我这样做的方式是否是个坏主意。

如果这是个坏主意,你能告诉我应该在哪里实例化这些类吗?请记住,Engine 中的许多函数都依赖于这些类的这些实例中的变量,我真的不想将大量参数传递给每个函数。

谢谢。

最佳答案

从类内部实例化成员对象会降低代码的模块化/灵 active 。

假设您对 ImageManager 有多种实现方式类(例如,在对 MockImageManager 进行单元测试时,您可能希望有一个 Engine,或者您可能希望与各种第三方一起试用 Engine ImageManager),这是您制作 Engine 的唯一方法使用 ImageManager 的一个实现或者另一种是通过修改 Engine 的实现本身。

这会阻止您利用 OOP 的动态调度,尤其是 C++(这里的关键词是:继承、接口(interface)和虚拟调用)。

你会发现你的代码会变得更加灵活,比如:

class Engine
{
public:
Engine(int w, int h, int tileSize, const std::shared_ptr<ImageManger>& im, const std::shared_ptr<GridClass>& gc);
protected:
std::shared_ptr<ImageManger> imageManager;
std::shared_ptr<GridClass> gridClass;
// ....
};

然后只需复制构造函数中给定的 shared_ptr:

Engine::Engine(int w, int h, int tileSize, const std::shared_ptr<ImageManger>& im, const std::shared_ptr<GridClass>& gc) : imageManager(im), gridClass(gc)
{
// ...
}

实例化地 block 的方式:

int main(void)
{
Engine engine(42, 42, 42, std::make_shared<ImageManager>(), std::make_shared<GridClass>());
// ...
return 0;
}

这样,您只需更改即可提供 ImageManager 的新实现(前提是ImageManager的接口(interface)是由虚拟调用组成的)就是把它编码成MyRevolutionaryImageManager (这将派生自 ImageManager ),并更改 std::make_shared主要调用std::make_shared<MyRevolitionaryImageManager>() .您甚至不必重新编译 Engine ,将使用新的实现(允许旧代码调用新代码的虚拟之美)!

当然现在如果ImageManager和/或 GridClass只是 Engine 的实现细节,如果不需要灵 active ,那么从 Engine 中实例化它们就足够公平了。 .

shared_ptr的使用不需要,您可以根据需要使用普通指针,但是您需要考虑何时/何处删除内容。

关于c++ - 在哪里实例化依赖于主类的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17428716/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com