magnus
magnus

Reputation: 4261

Should pointers be used to reduce header dependencies?

When creating a class that is composed of other classes, is it worthwhile reducing dependencies (and hence compile times) by using pointers rather than values?

For example, the below uses values.

// 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) {}

However, the modified version below uses pointers.

// 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)) {}

I've read a post that recommends such an approach, but if you have a large number of pointers, there'll be a large number of new calls, which I imagine would be slow.

Upvotes: 0

Views: 182

Answers (2)

Nicholas Smith
Nicholas Smith

Reputation: 1005

This is what most people call the Pimpl idiom (http://c2.com/cgi/wiki?PimplIdiom).

Simple Answer

I highly suspect that you do not have a good use case for this and should avoid it at all cost.

My Experience

The main way that Pimpl has ever been useful for me is to make an implementation detail private. It achieves this because you do not need to include the headers of your dependencies, but can simply forward declare their types.

Example

If you want to provide an SDK to someone which uses some boost library code under the hood, but you want the option of later swapping that out for some other library without causing any problem for the consumer of your SDK, then Pimpl can make a lot of sense.

It also helps create a facade over an implementation so that you have control over the entire exposed public interface, rather than exposing the library you implicitly depend on, and consequently its entire interface that you don't have control over and may change, may expose too much, may be hard to use, etc.

Upvotes: 3

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385295

If your program doesn't warrant dynamic allocation, don't introduce it just for the sake of project organisation. That would definitely be a false economy.

What you really want to do is attempt to reduce the number of inter-class dependencies entirely.

However, as long as your coupling is sensible and tree-like, don't worry too much about it. If you're using precompiled headers (and you are, right?) then none of this really matters for compilation times.

Upvotes: 2

Related Questions