C++ Trick: Removing the need for Forward Declarations

18 June, 2009 § 3 Comments

C++ is known to have lots of tricks. This is seen by some as a powerful asset and by others as a reason to stray away. I’m always fascinated by learning new features of C++ and have fun finding out more all the time.

During a recent code review, I noticed the  following code:

foo.h

#ifndef FOO_H
#define FOO_H

class foo {
};

#endif

bar.h

#ifdef BAR_H
#define BAR_H

class bar  {
 class foo* m_pFoo;
 bar();
};

#endif

bar.cpp

#include "bar.h"
#include "foo.h"

bar::bar() : m_pFoo( new foo )
{
} 

Notice anything  odd? How about line 5 in bar.h?

It turns out that there is no forward declaration needed in bar.h for the foo type if you write your declaration like so. The reason that this works is by prepending the typename with ‘class’, you are explicitly telling the compiler that foo is a type, and you are declaring a pointer to this type. If you did not prepend the declaration with class, then the compiler would have no way to know if you meant to multiply a variable named foo by another variable named m_pFoo.

You may have seen this idiom more with structs, like so:

struct POINT { 
int x;
int y;
};

struct POINT topLeft;

And so it turns out there is more! You can even replace that same line 5 with:

struct foo* m_pFoo;

This is because the C++ Standard says that a class can be declared as a struct and it is still a class. There is no difference when declaring a class or struct in C++. The only difference comes when the type is defined, in which struct causes bases and members to be public by default. [1]

I don’t recommend that you use this trick in production code, as it is likely to confuse other members of your team, and there is no performance savings by not typing the class name one more time and another semicolon, but you can definitely use this to stump one of your friends about your inner-knowledge of C++.

Update (June 22, 2009): The ability to do this comes from the pre-history of C. Within C and C++, you can create a struct/class and a non-struct/class with the same name, such as:

 struct stat { /* ... */ };
int stat( char* name, struct stat* buf ); 

When you use the struct/class, you have to prefix it with the keyword struct/class to disambiguate between the names. [2]

[1] D. Abrahams, A. Gurtovoy. C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond. Page 25.
[2] B. Stroustrup. The C++ Programming Language: 3rd Edition. Page 104.

Tagged: ,

§ 3 Responses to C++ Trick: Removing the need for Forward Declarations

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

What’s this?

You are currently reading C++ Trick: Removing the need for Forward Declarations at JAWS.

meta