gpt4 book ai didi

c++ - 如何保证单例不被过早销毁?

转载 作者:太空狗 更新时间:2023-10-29 23:46:26 26 4
gpt4 key购买 nike

在我的项目中,我正在使用大约 4 个单例来实现 Scott Meyer 的方式。其中之一:

LevelRenderer& LevelRenderer::Instance()
{
static LevelRenderer obj;
return obj;
}

现在,其中两个 Singletons,LevelRendererLevelSymbolTable 相互交互。例如,在这个方法中:

void LevelRenderer::Parse(std::vector<std::string>& lineSet)
{
LevelSymbolTable& table = LevelSymbolTable::Instance();

/** removed code which was irrelevant **/

// for each line in lineSet
BOOST_FOREACH(std::string line, lineSet)
{
// for each character in the line
BOOST_FOREACH(char sym, line)
{

/** code... **/

// otherwise
else
{
sf::Sprite spr;

// Used LevelSymbolTable's Instance here...
table.GenerateSpriteFromSymbol(spr, sym);
// ^ Inside LevelRenderer

/** irrelevant code... **/
}
}
}
}

现在,虽然问题还没有出现。我担心的是,如果 LevelSymbolTable 实例在我调用 GenerateSpriteFromSymbol 之前 已经被销毁怎么办?

由于我使用了 Scott Meyer 方式,所以 Singleton 的实例是由堆栈分配的。因此,使用 last created first destroyed 规则保证被销毁。现在,如果 LevelSymbolTable 的实例是在 LevelRenderer 的实例之后创建的,它将被销毁之前 LevelRenderer 的实例,对吧?那么,如果我在 LevelRenderer 中调用 LevelSymbolTable 的方法(尤其是在 LevelRenderer 的析构函数中),我将踏上未定义行为领域.

如前所述,这个问题实际上并没有在调试时出现,纯属我的假设和猜测。那么,我的结论正确吗? LevelSymbolTable 是否会在 LevelRenderer 之前被销毁。如果是这样,有没有办法摆脱这种困惑局面?

最佳答案

这里你什么都不用担心。* static 关键字保证它从初始化到程序退出都是可用的。因此,您可以在静态变量初始化后的任何时候对其进行调用。

另外,您有对 LevelSymbolTable 的引用,而不是局部变量。这就是类名后面的符号的意思。所以你可以在本地使用它,但它实际上是在“引用”存在于其他地方的真实对象。因此,当方法退出时,引用将超出范围,但它引用的对象不会。

*好吧,你可能不得不担心一件事。在析构函数中,您应该只是清理所有内存或文件引用或您可以处理的其他类似性质的东西。我不知道您为什么要在析构函数中调用其他对象。

关于c++ - 如何保证单例不被过早销毁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11373100/

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