我预计对象生命周期会出现一个奇怪的问题。我在范围内实例化了一个结构(范围的开头)。这个对象如下:
struct Spy
{
Spy(const std::string& p_name) : name(p_name)
{
start = std::chrono::steady_clock::now();
}
~Spy()
{
Destroy();
}
void Destroy()
{
end = std::chrono::steady_clock::now();
Save();
}
std::string name;
std::chrono::steady_clock::time_point start;
std::chrono::steady_clock::time_point end;
void Save() { Profiler::Save(*this); }
};
目标是计算 Spy 的生命周期,所以计时器应该在创建时开始(Ctor),计时器应该在销毁时停止并将数据保存在另一个类中(Dtor)。
这是 spy 用法:
ElkTools::Utils::Profiler::Spy spy("PostUpdate");
if (m_enableRendering)
{
m_windowManager->GetDriver()->ClearScreen();
RenderScene();
m_windowManager->GetDevice()->SwapBuffers();
}
m_inputManager->Update();
Context::Device::PollEvents();
spy.Destroy();
此代码运行良好,但当我不调用 destroy 方法(应该由 dtor 调用)时,耗时(结束 - 开始)非常低 (0.0000001)。是由于编译器优化吗?编译器是否检测到我没有调用此对象的任何方法,所以它会从堆栈中销毁它?
编辑: 好吧,我得到了答案。问题是我使用宏来创建 spy ,如下所示:
#define PROFILER_SPY(name) \
if (ElkTools::Utils::Profiler::__RUNNING) \
ElkTools::Utils::Profiler::Spy __profiler_spy__(name)
但我完全忘记了我的 if 语句是一个范围,所以在 if spy 被销毁之外......你有什么想法继续检查条件而不破坏 if 语句中的 spy 吗?
最佳答案
std::optional
或 std::unique_ptr
将是对此类问题的合理修复。
#define PROFILER_SPY(name) \
std::optional<ElkTools::Utils::Profiler::Spy> __profiler_spy__ = \
ElkTools::Utils::Profiler::__RUNNING
? std::make_optional<ElkTools::Utils::Profiler::Spy>(name)
: std::nullopt
或者使用std::unique_ptr
:
#define PROFILER_SPY(name) \
std::unique_ptr<ElkTools::Utils::Profiler::Spy> __profiler_spy__ = \
ElkTools::Utils::Profiler::__RUNNING
? std::make_unique<ElkTools::Utils::Profiler::Spy>(name)
: nullptr
关于c++ - 对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50318883/