【问题标题】:Should pointers be used to reduce header dependencies?是否应该使用指针来减少标头依赖性?
【发布时间】:2016-06-30 06:23:19
【问题描述】:

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

例如,下面使用值。

// 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 调用,我想这会很慢。

【问题讨论】:

  • “是否值得通过使用指针而不是值来减少依赖关系(从而减少编译时间)?” - 我不明白使用指针如何“减少依赖” - 也不知道它与编译时间有什么关系。
  • 没有关于需要调用new 的指针。我可以写一堆代码,到处都是指针,而不是一个 new 调用。
  • @Dai:您可以转发声明指针类型,而不是 #includeing 完全定义类型的整个标头。
  • @SamVarshavchik:问题中的代码不是指向自动存储持续时间变量的指针是安全的代码示例。有终身考虑。 OP 通常是正确的,这种方法将不可避免地导致更多(可能是过多的)动态分配。
  • @Dai 如果不发布实现,显然使用指针可以减少类实现更改的编译时间依赖性;这反过来又禁止使用普通对象(使用代码不知道它们的大小和布局)。这很简单。

标签: c++ pointers circular-dependency forward-declaration


【解决方案1】:

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

简单回答

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

我的经历

Pimpl 对我有用的主要方式是将实现细节设为私有。它实现了这一点,因为您不需要包含依赖项的标头,而可以简单地转发声明它们的类型。

示例

如果您想向在后台使用某些 boost 库代码的人提供 SDK,但您希望稍后将其换成其他库 不会给消费者带来任何问题使用您的 SDK,那么 Pimpl 会很有意义。

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

【讨论】:

  • 我在这里没有看到 Pimpl 的证据。
【解决方案2】:

如果您的计划不保证动态分配,请不要仅仅为了项目组织而引入它。那肯定是一种虚假的经济。

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

不过,只要你的耦合是合理的并且是树状的,就不用太担心了。如果你使用的是预编译的头文件(你是,对吧?),那么这些对于编译时间来说都不重要。

【讨论】:

  • 我认为问题还在于大型依赖树。某些标头中可能不相关的微小更改可能会导致大部分项目重新编译。对于可能令人望而却步的大型项目,例如防止夜间构建和测试。当我在汉堡的 Star Division(Star Office,后来的 OpenOffice)申请工作时,这是一个问题:“如果你想在一个多态类中添加一个虚函数而不重新编译所有使用这个类的文件;你把类声明中的新函数?” (最后,因为 VTable 中所有早期的偏移量都不会改变。)
  • “你真正想做的是尝试完全减少类间依赖的数量。”有关执行此操作的方法的任何参考资料?
猜你喜欢
  • 1970-01-01
  • 2013-12-15
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
相关资源
最近更新 更多