避免在标题中包含chrono
Avoid including chrono in header
我使用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
),则其他代码将毫无理由地停止使用编译。
显然,那个忘了添加include的家伙做错了。但很明显,无论我们喜不喜欢,这种情况都会发生。
其他信息
由于它可能与某些解决方案相关,因此经常调用SomeMethod()
,在我的场景中性能很重要。
如果time_point
是一个自定义类型,问题就会得到解决,因为这样您就可以向前声明它,将成员更改为(唯一)指针,并将include移到.cpp文件中。然而,std
类型的前向声明是未定义的行为,因此这是不可能的。这基本上给你留下了以下选项:
- 将
std::chrono::time_point<std::chrono::steady_clock>
封装在自定义类中。然后,您可以安全地向前声明该类型,将成员更改为(唯一)指针,并将自定义类(包括<chrono>
)的include移到.cpp文件中 - 使用pimpl习惯用法,将类的整个实现移动到.cpp文件中
我理解你的动机。尽管如此,尽管你认为有人使用<chrono>
并忘记包含它的场景并不牵强,但这是那个人的问题,而不是你的问题。因此,您应该考虑是否真的有必要引入一些复杂性,只是为了隐藏<chrono>
标头。标准库包含通常不会造成伤害,尤其是因为它们不会引入重建影响。
正如其他人所指出的,为pimpl习惯用法或前向声明类型使用智能指针将引入另一个include,即<memory>
。尽管这通常是一个比<chrono>
更常见的标头,但您只是将一个include交换为另一个。因此,如果您真的想避免额外的include,您可能需要使用原始指针。但是,您必须处理其他问题,例如复制和移动操作。
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 编译包含字符串的代码时遇到问题
- c++库的公共头文件中应该包含什么
- 将包含C样式数组的对象初始化为成员变量(C++)
- 是否需要删除包含对象的"pair"?
- 如何在c++迭代器类型中包装std::chrono
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 使用mongocxx驱动程序时包含头文件问题
- 如何在h文件中包含.o对象文件
- 在混合代码库中将C转换为C++时出现许多包含错误
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- cmath抛出错误C2062、C2059、C2143和C2447.cmath包含在矢量文件中
- 为什么您需要C++头文件的包含保护
- 无法在UE4中包含BP类到CPP类
- 避免在标题中包含chrono
- 包含<chrono>时出错
- 问题 C1083:无法打开包含文件:"chrono":没有弹出此类文件或目录