C++ D Pointer implementation
I am a software engineer by profession; so its natural that I post about some programming topics every now and then. A couple of days ago; I posted about some C++ coding guidelines. That post was mainly for some standards to keep in mind for header files. One thing that I mentioned in there was the use of a ‘d pointer’. It is also known as the Cheshire Cat implementation . The main idea here is to hide the implementation details from the user. The header file should only list the public interface; since that is the only interface the user is going to be using. Read more for a example of how to write a d ptr type implementation.
This example will use a bank account object. Think of it as a Bank Savings account. There are two files: Account.h and Account.cpp. It is a common practice to name the d ptr as ‘ClassNamePrivate’. So in this case; it will be called AccountPrivate.
NOTE: This example may not be for a very useful c++ object; it is merely being used to show you the d ptr implementation.
// forward declaration
class AccountPrivate;class Account {
public:
Account();
~Account();
double getBalance() const;
double getInterestRate() const;private:
AccountPrivate* m_d;
};
That is it for the header file. Notice how the only thing the user knows about it is the public functions that he/she has access to and the d ptr.
Now lets look at the implementation. This file is Account.cpp
class AccountPrivate {
public:
void updateBalance();
void deductFees();double m_balance;
double m_rate;
double m_interest;
};void AccountPrivate::updateBalance() {
m_balance = m_rate * m_balance;
}void AccountPrivate::deductFees() {
m_balance = m_balance - 5.0;
}Account::Account() : m_d (new AccountPrivate) {
// default constructor
m_d->m_balance = 1000.0;
m_d->m_rate = 4.2;}
void AccountPrivate::updateBalance() {
m_balance = m_rate * m_balance;
}double Account::getBalance() const {
return m_d->m_balance;
}double Account::getInterestRate() const {
return m_d->m_rate;
}Account::~Account() {
delete m_d;
}
Thats it. You can implement the d ptr fully in the implemenation (.cpp) file and this way the user has no idea about your implementation details. This is what information hiding is all about.
Thoughts?
The benefits seem fairly marginal and hard to define. Have you figured out the overhead of the implementation? I’m all for improvements, if they don’t cost more than they’re worth.
I would say that the main benefit is that you are hiding the inner workings of your class from your user. Think about it in the sense of an API that you are shipping out to your users. You can just give them a shared library and your include files; and they can use your api without having any knowledge into the implementation details.
This is used widely in Qt Toolkit. It will help reduce the compilation time.
Nice idea, I’m a great fan of this kind of implementation hiding and makes your code seem very tightly and securely packed. My only problem with this is that since there is no definition in the .h file it isn’t possible to have inline get/set functions should you need them. Not a huge problem, but if (like me) speed is a big issue, then the penalty may not be worthwhile…
@BenB
Well, you can inline the functions in your private implementation. And calling them from your public interfaces should result in code expansion rather than a function call
The most important benefice i think is that if you modify the private part of the class, you don’t touch the public class header so you don’t have to recompile every files that use the class.
For some classes that are used everywhere, it can compile in a few seconds instead of a full rebuild.
Excellent article.
I use incomplete types extensively in C. This is a natural progression.
[...] http://jatshergill.com/blog/2006/04/05/d-pointer-implementation/ [...]