Discussing the nuts and bolts of software development

Thursday, August 23, 2007

 

Pay it Forward: Part 2

When writing C++ classes and interfaces (e.g. abstract classes), do your compiler a favor and declare each class in its own header file whenever you can. Trust me, it'll pay you back later.

Rule of thumb:
If you ever need to use the would-be nested class without using the nesting class, then your class should not be nested.
To see how nested classes should be used, look at std::string::iterator. It's a nested type (Okay, okay, it could be a nested typedef that could alias a non-nested class. From outside std::string, it looks like a nested class and that's all that matters.) that's useless without its nesting class std::string.

Now, here's an example of how not to use your nested types:

AddressBook.h

// Forward type declaration
class Contact; // Remember this?

class AddressBook
{
public:
// Interface to be implemented by objects wanting AddressBook notifications.
class IContactEventSink
{
public:
virtual void onContactChanged(Contact const& oldContact, Contact const& newContact) = 0;
};
...
};
With the the above implementation, whenever someone wants to receive notification from the AddressBook, they need to include the AddressBook itself and derive from AddressBook::IContactEventSink. Doing this has the following down sides:
To fix all of this and to give your compiler a break, declare the IContactEventSink class in its own header and include this header whenever you need the full definition.

IContactEventSink.h

// Forward type declaration
class Contact; // Yup, even here.

class IContactEventSink
{
public:
virtual void onContactChanged(Contact const& oldContact, Contact const& newContact) = 0;
};
Then, hit "Build", sit back and wait to...

... actually no. You can get on with your life. Your incremental build is now done because you've paid it forward!

Labels: , , ,


This page is powered by Blogger. Isn't yours?