1

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)?

moki
  • 2,259
  • 1
  • 19
  • 39
  • 3
    [PImpl](http://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B)? – n0rd Jun 11 '15 at 00:23
  • _"A link or reference to some article for further reading is appreciated."_ Duped it so far. Is that also OK for you, instead of writing up an answer myself? – πάντα ῥεῖ Jun 11 '15 at 00:26
  • 1
    @πάνταῥεῖ All I needed was the name to research it further. My efforts in trying to describe a programming language technique to a bot (a.k.a Google) was pointless. If you think there's something good to know and hard to find please go ahead and write an answer. – moki Jun 11 '15 at 00:34
  • @Barracuda -- a code example would be great. – Soren Jun 11 '15 at 00:41
  • @Soren I don't think so. The problem was finding the technical terminology of a design technique. The class names provided in the description belong to an open source and free software called Qt which is readily available over the Internet. – moki Jun 11 '15 at 00:46
  • @Barracuda: You don't have to write your own code example, but providing a link directly to the one you're looking at is very helpful. If you dig up a link and put it in the question, one person puts in time (you), and it's your question anyway. If you leave it up to the reader, then 100 readers may waste their time.... or merely decide your question isn't interesting enough to go digging through the internet for Qt source code. – Ben Voigt Jun 11 '15 at 00:54
  • @BenVoigt I am reading the source code of Qt which I have downloaded from it's official website on my own computer. There's no direct link to the class source for which I've provided the name in my description. If you have the Qt libraries installed on your system you can look at the headers. – moki Jun 11 '15 at 01:01
  • @Barracuda: So [this link clearly is not working](https://qt.gitorious.org/qt/qt/source/8ab1ad64620ff9d0453a326010d161ea68a63a2f:src/gui/graphicsview/qgraphicsitem.h#L88) ? Anyway, if you mean to ask a question that only Qt programmers can answer, please do tag it [tag:qt]. – Ben Voigt Jun 11 '15 at 01:05
  • And from the usage of `Q_DECLARE_PRIVATE`, google probably would have brought you to http://zchydem.enume.net/2010/01/19/qt-howto-private-classes-and-d-pointers/ – Ben Voigt Jun 11 '15 at 01:07
  • @BenVoigt I don't see any problem here but if you think we need to discuss this any further please move it to a chat to avoid clutter in the comments section. – moki Jun 11 '15 at 01:13

2 Answers2

2

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.

tahsmith
  • 1,463
  • 15
  • 22
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.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 83,259
  • 13
  • 96
  • 175
  • sorry but had to point it out here because it's impossible to fix a single character in edit. In class `A` constructor implementation, `pinpl` must be changed to `pimpl`. – moki Jun 11 '15 at 16:29