避免在标题中包含chrono

时间:2017-11-06 07:45:37

标签: c++ c++11

我正在使用std::chrono来跟踪从实例化到每次调用someMethod()所经过的时间。

最小样本代码如下所示:

#include <chrono>

class TestClass
{
public:
    TestClass();
    void someMethod();

private:
    std::chrono::time_point<std::chrono::steady_clock> m_timeBegin;
};
TestClass::TestClass() :
    m_timeBegin(std::chrono::steady_clock::now())
{
}

void TestClass::someMethod()
{
    auto timeNow = std::chrono::steady_clock::now();
    auto msSinceCreation = 
         std::chrono::duration_cast<std::chrono::milliseconds>(timeNow - m_timeBegin);
}

我想摆脱标题中的#include

动机

除编译和链接时,我主要关心的是封装。使用std:chrono仅与实施相关。为了使用Testclass,绝对不需要使用它,甚至不需要知道它。

以下是一些可能的情况。如果使用TestClass的人决定使用std::chrono,他可以在不添加#include的情况下执行此操作。然后,如果将来TestClass更改的实施停止使用std:chrono(并因此删除#include)其他代码将停止使用无理由进行编译

显然那个忘记添加包含的人做错了。但显然我们会喜欢或不喜欢这种情况。

其他信息

由于它可能与某些解决方案相关,因此SomeMethod()经常被调用,性能在我的场景中很重要。

1 个答案:

答案 0 :(得分:6)

如果WARNING是自定义类型,您的问题就会得到解决,因为这样您就可以转发声明它,将成员更改为(唯一)指针,然后将include移动到.cpp文件。但是,time_point类型的前向声明是未定义的行为,因此这是不可能的。这基本上使您可以使用以下选项:

  • std换行到自定义类中。然后,您可以安全地转发声明该类型,将成员更改为(唯一)指针,并将自定义类(包括std::chrono::time_point<std::chrono::steady_clock>)的包含移动到.cpp文件中。
  • 使用pimpl惯用法并将类的整个实现移动到.cpp文件中。

我理解你的动机。尽管如此,虽然有人使用<chrono>而忘记包含它的情况并不遥远,但这是某个人的问题,而不是你的问题。所以你应该考虑是否真的有必要引入一些复杂性,只是为了隐藏<chrono>标题。标准库包括通常不会受到伤害,特别是因为它们不会引入重建影响。

正如其他人所说,使用智能指针作为pimpl习惯用法或前向声明类型会引入另一个包含,即<chrono>。虽然这通常是比<memory>更常见的标题,但您只是将一个包换成了另一个。因此,如果您真的想避免使用其他包含,则可能需要使用原始指针。但是你必须处理其他问题,例如复制和移动操作。