我期待对象生命周期的奇怪问题。我在范围中实例化了一个结构(范围的开头)。这个对象如下:
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),计时器应该停止并在destroy(Dtor)上的另一个类中保存数据。
这是间谍用法:
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)。是否由于编译器优化?编译器是否检测到我没有调用此对象的任何方法,因此它会从堆栈中销毁它?
编辑: 好吧,我得到了答案。问题是我使用宏来创建间谍,如下所示:
#define PROFILER_SPY(name) \
if (ElkTools::Utils::Profiler::__RUNNING) \
ElkTools::Utils::Profiler::Spy __profiler_spy__(name)
但是我完全忘记了我的if语句是一个范围,所以除了间谍被破坏之外.....你是否有任何想法继续检查条件而不破坏if语句中的间谍?
答案 0 :(得分:3)
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
答案 1 :(得分:1)
只需使用std :: unique_ptr作为后卫并在工厂中构建它。
std::unique_ptr<Spy> SpyFactory()
{
if (ElkTools::Utils::Profiler::__RUNNING)
return std::make_unique<Spy>()
else
return nullptr;
}
要禁用分析,只需让工厂返回一个nullptr,让编译器优化其余部分:)
请确保不要在nullptr上调用.Destroy():)