gpt4 book ai didi

c++ - 如何最好地处理 C++ 对象初始化 : empty constructors or pointers?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:19:32 25 4
gpt4 key购买 nike

我想知道对于必须具有相对较大范围/较长生命周期的对象,进行对象初始化和存储的最佳方法是什么。假设我们有一个 GameEngine 类需要初始化并保存对 Window 的引用以进行渲染。在程序的整个生命周期中都需要引用,窗口至少需要知道它的尺寸。

在 Java 中,我会这样做:

// Declaration:
Window window;
// Initialization:
window = new Window(width, height);

据我所知,在 C++ 中,第一个已经调用了 Window 类的默认构造函数,因此是声明初始化。因此,window = Window(width, height); 将是赋值,丢弃已经存在的对象。

我能找到的第一个解决方案是使用指针:

// GameEngine.hpp
class GameEngine {
Window *window;
};

// Somewhere in GameEngine.cpp:
window = new Window(width, height);

但话又说回来,我经常阅读 one should favor plain objects over pointers when possible,事实上,我很快就陷入了指针的困惑之中,所以我正在寻找另一种方法。

另一种解决方案似乎是将您的对象设计为具有不带参数的构造函数并稍后设置对象:

// GameEngine.hpp
class GameEngine {
Window window;
};

// Somewhere in GameEngine.cpp
window.setWidth(width);
window.setHeight(height);

这可行,但有一个严重的缺点:对象(至少在这种情况下)可能处于不一致状态,因为在不设置宽度/高度的情况下尝试显示窗口会导致错误或崩溃。它对某些对象有效,但对大多数对象无效。

避免这种情况的一种方法是使用默认值。例如,Window 类的构造函数可能如下所示:

Window::Window(int width = 800, int height = 600) {}

或者甚至那样:

Window::Window() : width(DEFAULT_WIDTH), height(DEFAULT_HEIGHT) {}

但在很多情况下,默认值很难确定。另外,他们应该从哪里来? Window 类是否应该定义 DEFAULT_WIDTHDEFAULT_HEIGHT或者我应该这样做吗?

// GameEngine.hpp
class GameEngine {
static const int DEFAULT_WIDTH = 800;
static const int DEFAULT_HEIGHT = 600;
Window window(800,600);
};

但这似乎很糟糕,正如我读到的那样,您不应该在 header 中进行任何初始化,而只能在声明中进行,因此 DEFAULT_WIDTHDEFAULT_HEIGHT 的值不应该实际上此时已知(并且仅在 .cpp 中初始化,对吗?)。

我是否遗漏了一个选项?或者在 C++ 中是否普遍认为程序员应该知道他在做什么并在使用它们之前注意让他的对象处于一致状态? 什么时候使用哪种方法?

最佳答案

如果你只想构造它一次并且它可以在类的初始化中完成,那么你不需要指针。您可以将其声明为成员并在构造函数中对其进行初始化,如下所示:

HPP

class Game
{
private:
Window window_;

public:
Game(int, int);
}

CPP

Game::Game(int width, int height) : window_(width, height)
{
}

这将在您构造 Game 对象时构造 window 对象,并且它将持续存在直到 Game 对象被销毁。如果您希望以后能够构造它或随时重建它,请像这样使用 std::unique_ptr :

HPP

class Game
{
private:
std::unique_ptr<Window> window_;

public:
Game(int, int);
void SomeMethod(int, int);

}

CPP

Game::Game(int width, int height)
{
window_ = std::make_unique<Window>(width, height);
}

Game::SomeMethod(int width, int height)
{
window_ = std::make_unique<Window>(width, height);
}

这将在 Game 对象被销毁时自动删除窗口,并在您每次调用 std::make_unique 构建新窗口时自动删除窗口。这是一些关于 unique_ptr 的文档: http://en.cppreference.com/w/cpp/memory/unique_ptr

关于c++ - 如何最好地处理 C++ 对象初始化 : empty constructors or pointers?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30631467/

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