一个非常常见的编码实践是通过在每个类的基础上使用.h
和文件将类的接口与其成员函数的实现分开。.cpp
所以class Foo
会用一个Foo.h
头文件和一个相应的Foo.cpp
文件来实现。
在泛型类的特殊情况下,这通常被抛到窗外,而是使用仅标头库来保持编译器满意,即使它确实使接口文件与实现细节混淆。
我最近遇到了一些如下编写的代码。该.h
文件包含接口和一个#include
包含.hpp
通用成员函数实现的文件。
例如对于类型 T 的简单容器
Value.h
#ifndef VALUE_H
#define VALUE_H
template <typename T>
class Value
{
public:
Value(T value);
void set(T value);
T get() const;
private:
T data;
};
#include "Value.hpp"
#endif
和相应的Value.hpp
#ifndef VALUE_HPP
#define VALUE_HPP
template <typename T>
Value<T>::Value(T value) : data(value)
{
}
template <typename T>
void Value<T>::set(T value)
{
data = value;
}
template <typename T>
T Value<T>::get() const
{
return data;
}
#endif
这具有更好地分离接口和实现的优点,以及实际编译的进一步好处(在我有限的测试中)。
我的问题是,采用这种约定是否有任何隐藏的陷阱?