是否应该使用指针来减少标头依赖性

Should pointers be used to reduce header dependencies?

本文关键字:依赖性 指针 是否      更新时间:2023-10-16

当创建一个由其他类组成的类时,是否值得通过使用指针而不是值来减少依赖关系(从而减少编译时间)?

例如,下面使用值。

// ThingId.hpp
class ThingId
{
    // ...
};
// Thing.hpp
#include "ThingId.hpp"
class Thing
{
public:
    Thing(const ThingId& thingId);
private:
    ThingId thingId_;
};
// Thing.cpp
#include "Thing.hpp"
Thing::Thing(const ThingId& thingId) :
    thingId_(thingId) {}

但是,下面的修改版本使用指针。

// ThingId.hpp
class ThingId
{
    // ...
};
// Thing.hpp
class ThingId;
class Thing
{
public:
    Thing(const ThingId& thingId);
private:
    ThingId* thingId_;
};
// Thing.cpp
#include "ThingId.hpp"
#include "Thing.hpp"
Thing::Thing(const ThingId& thingId) :
    thingId_(new ThingId(thingId)) {}

我读过一篇推荐这种方法的文章,但是如果你有大量的指针,就会有大量的new调用,我想这会很慢。

这就是

大多数人所说的痘痘成语(http://c2.com/cgi/wiki?PimplIdiom)。

简单的答案

我高度怀疑您没有一个好的用例,应该不惜一切代价避免它。

我的经历

Pimpl 对我有用的主要方式是将实现细节设为私有。 它之所以能够实现这一点,是因为您不需要包含依赖项的标头,而只需向前声明其类型即可。

如果你想向在后台使用一些提升库代码的人提供一个SDK,但你想选择稍后将其换成其他库,而不会给SDK的使用者带来任何问题,那么Pimpl可以很有意义。

它还有助于在实现上创建外观,以便您可以控制整个公开的公共接口,而不是公开您隐式依赖的库,因此您无法控制并可能更改的整个接口可能会公开太多,可能难以使用等。

如果你的程序不保证动态分配,不要仅仅为了项目组织而引入它。那肯定是一个虚假的经济。

您真正想做的是尝试完全减少类间依赖项的数量。

但是,只要您的耦合是合理的并且像树一样,就不要太担心它。如果你使用的是预编译头(你是,对吧?),那么这些对于编译时间来说都无关紧要。