对象的生命周期

时间:2018-05-13 17:40:34

标签: c++ time chrono

我期待对象生命周期的奇怪问题。我在范围中实例化了一个结构(范围的开头)。这个对象如下:

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语句中的间谍?

2 个答案:

答案 0 :(得分:3)

std::optionalstd::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():)