Friday, May 20, 2005

Using Interfaces in C++ (III - final, I promise)

[UPDATE 2005/06/01] I submitted this article to CodeProject today.

Shortly after my last post, I did find a way to do what I said wasn’t possible: using the __interface keyword (a Microsoft extension) along with an enforced virtual destructor. For those interested in the topic, other resources related to using interfaces in C++ are included in this post too.

The solution I found was actually rather simple: the name for the desired interface is actually used to declare a class that contains a virtual destructor and inherits from an __interface that contains the actual methods. The macros are now defined as follows:

// cppinterfaces.h
 
#define DeclareInterface(name) __interface \
actual_##name {
 
#define EndInterface(name) }; \
class name : public actual_##name { \
public: \
virtual ~name() {} \
};

Here is how you declare an interface using the above defined macros:

// ibar.h
 
#include "cppinterfaces.h"
 
DeclareInterface(IBar)
int GetBarData() const;
void SetBarData(int nData);
EndInterface(IBar)

As you may have noticed, these new macro definitions require using the name of the wanted interface (ie: IBar) twice, first for DeclareInterface(), and then for EndInterface(). This introduces an always undesired redundancy, which made me struggle for a while trying to eliminate but failed. If anyone finds a way to define the macros so as to avoid requiring the same name twice, please let me know.

On the other hand, providing you don’t mind sacrificing portability to anything but MS compilers starting from VS7, the new macros have many advantages over their predecessors, simply because every requirement for an interface (only pure virtual methods, no data members, virtual destructor for implementing classes) is now automatically enforced. You don’t even need to explicitly declare interface methods as virtual or pure virtual (“= 0”), although the compiler won’t complain if you do so.

Before closing the topic, I’d like to include some links to related resources, which I found while doing research for these three posts. I plan on submitting an article covering what I posted here to CodeProject too and I’ll update this post in order to include a link to it as soon as it becomes available. [UPDATE 2005/06/01] I submitted this article to CodeProject today.

The techniques described here allow defining and implementing interfaces in C++ through the use of abstract base classes. Some people don’t like this as a solution because it forces every implementing class to have (and use) a virtual table and they find this unacceptable due to the space (the virtual table for each class) and performance (the indirection in each method call) penalties it imposes. As an alternative, Brian McNamara and Yannis Smaragdakis from the Georgia Institute of Technology wrote a paper “Static interfaces in C++,” which was published in the First Workshop on C++ Template Programming, Erfurt, Germany, October 10 2000.

Christopher Diggins wrote a proposal for a modification of the C++ language, in order to make it support interfaces without virtual functions. I have no idea whether this proposal was actually presented or considered by the standard committee.

Dr. Dobb's Journal August 1998, includes an article by Fred Wild, "Keeping interfaces and implementations separate," which discusses some ways to do so in C++ code.

Last but not least, the father of C++ Bjarne Stroustrup himself, made interesting comments about interfaces and C++ in an interview by Bill Venners in November 2003.

That’s all. I promise not to bother you with this interface stuff anymore. :)

Labels: ,

2 Comments:

Post a Comment

Links to this post:

Create a Link

<< Back to Main Page