Question

In C++ it's common to see things such as:

Header of class C

//== C.h ==//
#pragma once
#include "B.h"

class C
{
    B b;
};

Header of class B

//== B.h ==//
#pragma once
#include "A.h"

class B
{
    A a;
};

Header of class A

//== A.h ==//
#pragma once

class A
{

};

Because C.h includes B.h, and B.h includes A.h; C.h ends up knowing implementation details about A.h. In this case the headers are included only three levels deep, but in large projects including one header can quickly lead to the inclusion of hundreds of additional headers. Also resulting in long compile times.

In C++ 11 I could declare the headers as following:

Header of class C:

//== C.h ==//
#pragma once
#include <memory>

// proto
class B;

class C
{
    std::unique_ptr<B> b;
};

Header of class B

//== B.h ==//
#pragma once
#include <memory>

// proto
class A;

class B
{
    std::unique_ptr<A> a;
};

Header of class A

//== A.h ==//
#pragma once

class A
{

};

When replacing all members (class, struct) with smart pointers, I can include C.h without having to know the implementation of class B. Every cpp file now only has to know about it's members, without having to know about the memory layout of it's members.

My question would be:

  • Is it good design practice (a good idea) to replace all class members, that are either class and struct, with unique pointers? Are their additional pro's or cons ?
Was it helpful?

Solution

Straight direct data members support copying by default, if their types support copying. And it's maximally efficient. If one feels that it's worth it to trade that for shorter build time, then why use C++, why not instead (then) just use a language that leverages such tradeoff maximally, such as Java or C#.

In other words, it appears to be an ungood idea.

For shorter build times while still using C++, consider faster machine or build server park.

OTHER TIPS

It's not a good idea to replace all members with pointers, as it would add an extra layer of dereferencing. A direct member is actually allocated within the containing object, so accessing it is only requires a fixed offset from the containing object's location.

If you hide everything behind pointers, you would need to access the pointer member, then dereference the pointer to access the data (which will be somewhere else in memory). It's a trivial overhead on an individual basis, but it would soon add up if the principle was expanded across an entire program.

Another issue to bear in mind is maintainability. If you store everything via pointers then you need to manually including appropriate construction and copying. That can lead to various problems on a large project, as it increases the likelihood of programmer error. By contrast, the compiler does a lot of that automatically if you're using direct members.

An alternative that's worth looking-up is the PIMPL design pattern (Private Implementation, or Pointer to Implementation). It's essentially a way of hiding the private details of a class inside its source file, with a view to reducing header dependencies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top