max
max

Reputation: 2657

Terminology or name required

In many C++ source codes I see that while designing a class that might be sub-classed there's a forward declaration or reference to another similarly named class with a private or Private appended to the end of the original class name. For example in Qt there's a class named QGraphicsItem and in the beginning of the header file there's a forward declaration of QGraphicsItemPrivate. I tried looking in design pattern names and searched google trying to see if I can find what such design technique or method is called but It didn't yield any results. What's the name of this approach? What is / are the benefit(s)?

Upvotes: 1

Views: 82

Answers (2)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

I think there's a lot of your questions explained here: The Pimpl Idiom in practice.

But well, as you're explicitly asking for another answer:

"What's the name of this approach?"

It's widely called the Pimpl idiom, there are other (maybe more serious) equivalent terms in use, like e.g. opaque pointer).

The pattern generally looks like this:

A.h:

class AImpl;

class A {
public:
    A();
    ~A();
    void foo();
    void bar();
private:
    AImpl* pimpl;
};

A.cpp:

// Changing the following code won't have impact for need to recompile 
// external dependants
// *******************************************************************
// * Closed black box                                                *
// *******************************************************************
     struct AImpl {
        void foo();
        void bar();
     };

// *******************************************************************
// * lengthy implementation likely to change internally goes         *
// * here                                                            *
// *******************************************************************
     void AImpl::foo() {
     }
     void AImpl::bar() {
     }
// * /Closed black box                                               *
// *******************************************************************

// The public interface implementation just delegates to the
// internal one:
A::A() : pimpl(new AImpl()) { 
}

A::~A() { 
    delete pimpl;
}

void A::foo() {
    pimpl->foo();
}

void A::bar() {
    pimpl->bar();
}

"What is / are the benefit(s)?"

Any code including A.h will just refer to the public interface, and doesn't need to be recompiled due to changes made in the internal implementation of AImpl.
That's a big improvement, to achieve modularization and implementation privacy.

Upvotes: 1

tahsmith
tahsmith

Reputation: 1723

Sounds like the pimpl idiom. It goes by other names too, e.g., cheshire cat.

e.g.,

class FooPrivate;
class Foo
{
public:
    Foo();
    ~Foo();
    int GetInt();
private:
    FooPrivate* implPtr;
};

in implementation file,

class FooPrivate
{
    public:
    int x = 0;
};

Foo::Foo() : implPtr(new FooPrivate()) {}

Foo::~Foo() { delete implPtr; }

int Foo::GetInt()
{
    return implPtr->x;
}

It is used to hide implementation details of Foo. All data members and private methods are stored in Private. This means a change in the implementation does not need a recompile of every cpp file using Foo.

In the Qt source it is in qgraphicsitem_p.h. You can see it only stores data members and other implementation details.

Upvotes: 2

Related Questions