Время жизни объекта - PullRequest
0 голосов
/ 13 мая 2018

Я ожидаю странную проблему с временем жизни объекта. Я создал структуру в области видимости (начало области). Этот объект выглядит следующим образом:

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); }
};

Цель состоит в том, чтобы рассчитать время жизни шпиона, поэтому таймер должен начинаться с создания (Ctor), а таймер должен останавливаться и сохранять данные в другом классе при уничтожении (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), истекшее время (end-start) очень и очень мало (0.0000001). Это связано с оптимизацией компилятора? Обнаруживает ли компилятор, что я не вызываю какой-либо метод этого объекта, поэтому он уничтожает его из стека?

РЕДАКТИРОВАТЬ: Ну, я получил свой ответ. Проблема заключалась в том, что я использовал макрос для создания шпиона следующим образом:

#define PROFILER_SPY(name) \
  if (ElkTools::Utils::Profiler::__RUNNING) \
    ElkTools::Utils::Profiler::Spy __profiler_spy__(name)

Но я полностью забываю, что мое утверждение if является областью действия, поэтому за пределами, если шпион уничтожен ..... У вас есть идея продолжать проверять условие, не уничтожая шпиона в операторе if?

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

просто используйте std :: unique_ptr в качестве охраны и создайте его на фабрике.

std::unique_ptr<Spy> SpyFactory()
{
if (ElkTools::Utils::Profiler::__RUNNING)
     return std::make_unique<Spy>()
else
     return nullptr;
}

чтобы отключить профилирование, просто позвольте фабрике вернуть nullptr, пусть компилятор оптимизирует остальное:)

не вызывайте .Destroy () для nullptr:)

0 голосов
/ 13 мая 2018

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
...