请注意,在标头中公开实现细节可能有好处,也有在细节更改时强制重新编译的缺点;函数可以更容易地内联,这可以提高运行时性能。您将需要决定在何时何地进行这种权衡是值得的。
通过引入额外的间接级别,可以将所有私有实现细节隐藏在源文件中。一种常见的方法是指向私有实现(或“pimpl”)的指针,例如:
// Header file
class Thing {
public:
Thing(...);
~Thing();
// Public interface
private:
struct Impl;
std::unique_ptr<Impl> impl;
};
// Source file
struct Thing::Impl {
// private details
};
Thing(...) : impl(new Impl(...)) {}
~Thing() {}
// Implementation of public interface
另一种可能性是定义一个抽象接口,使用一个或多个工厂来创建包含实现的具体实例,例如:
// Header file
class Thing {
public:
virtual ~Thing() {}
static std::unique_ptr<Thing> make(...);
// Pure virtual public interface
};
// Source file
class ThingImpl : public Thing {
// Implementation of public interface
// Private implementation details
};
std::unique_ptr<Thing> Thing::make(...) {
return std::unique_ptr<Thing>(new ThingImpl(...));
}
这两种方法都将所有实现细节放在一个源文件中,因此当细节发生变化时,这是唯一需要重新编译的东西。但是两者都引入了额外的指针间接和/或间接函数调用,这可能会影响运行时性能。