views:

394

answers:

2

I am curious about the impact my typedef approach has on my builds.

Please consider the following example.

#include "SomeClass.h"

class Foo
{
    typedef SomeClass SomeOtherName;

    SomeOtherName* storedPointer;

    void setStoredPointer(SomeOtherName* s);
}

void Foo::setStoredPointer(SomeOtherName* s)
{
    storedPointer = s;
}

Whenever I end up with situations like above, this drives the typedef into the header file and thus, requiring I #include it in the header file. I am concerned the lack of forward declarations may be causing longer build times.

Based on comments from this post:

Forward declaration of a typedef in C++

I can forward declare the class, typedef a reference or pointer, and then #include inside the .cpp file. This should then permit for faster build times. Am I correct in my conclusions about this?

If so, I would end up with a typedef such as this:

typedef SomeClass* SomeOtherNamePtr;
typedef SomeClass& SomeOtherNameRef;
typedef const SomeClass* SomeOtherNameConstPtr;
typedef const SomeClass& SomeOtherNameConstRef;

This doesn't look like very clean code to me, and I think I have read articles/postings (not necessarily on SO) recommending against this.

Do you find this acceptable? Better alternatives?


Update: Using Michael Burr's answer, I was able to solve the case of pointers and references only. However, I ran into a problem when trying to take the sizeof() in my function. For example, say the class has the following function:

//Foo.h
class Foo
{
    typedef class SomeClass SomeOtherName;

    void doSomething(const SomeOtherName& subject)
}

//Foo.cpp
#include "Foo.h"
#include "SomeClass.h"
void Foo::doSomething(const SomeOtherName& subject)
{
    sizeof(subject); //generates error C2027: use of undefined type 'SomeClass';
    sizeof(SomeClass); //generates same error, even though using the sizeof()
                       //the class that has been #include in the .cpp.  Shouldn't
                       //the type be known by now?
}

Alternatively, this would work.

//Foo.h
class SomeClass;
class Foo
{
    void doSomething(const SomeClass& subject)
}

//Foo.cpp
#include "Foo.h"
#include "SomeClass.h"
void Foo::doSomething(const SomeClass& subject)
{
    sizeof(subject);
    sizeof(SomeClass);
}

I'm using Microsoft Visual C++ 6.0. Is this a bug of the compiler or is this in general against the standard?

In the example that has the error, please note that a sizeof(SomeClass) is the original class that is being typedef, not the new typedef type being created in Foo. I'm surprised that by doing a forward declaration in a typedef is restricting my ability to do anything with the class that is being typedef.


Followup: Just tested it using the XCode compiler and I believe my sizeof question was a Visual C++ 6.0 compiler issue. I'd guess that the XCode compiler is probably correct, but I don't have anything else to try at the moment. So, while this was informative, I personally am out of luck on my current task since the best answer doesn't work for my situation.

+1  A: 

Would

typedef class SomeClass SomeOtherName;

do the trick for you?

With that, the compilation unit that's using the typedef only for pointers or references doesn't need to #include the SomeClass header.

Michael Burr
I tried your suggestion, and indeed it solves the specific case of where the class deals entirely with pointers and references. However, I am finding that in .cpp files that try and do something with the class (taking the sizeof()) in my case, still have a problem. I will update the question with an example.
FP
That's as designed. The compiler can't figure out the size of an object without knowing the actual definition of it.
Josh Matthews
When dealing with an incomlete type, you can declare references or pointers to the type but you can't do much else, since all the compiler knows is the name, but nothing else about the type. Using refs/pointers to incomplete types allows the header file for a class to avoid being dependent on another header, but the implementation will still need to include the full declaration of the target type. Using incomplete types may prevent you from being able to implement methods inline.
Michael Burr
Well, I just tested my last question on a different compiler, and it seems as if my followup question really was a Visual C++ 6.0 issue. I tested on my mac and it was able to resolve the type and its size when I included the header in the implementation file.
FP
A: 

Am I correct in my conclusions about this?

Yes. One of the answer in the question you referenced suggests that you can:

//forward declaration instead of #include "SomeClass.h"
class SomeClass;
//now this works even without #include "SomeClass.h"
typedef SomeClass SomeOtherName;

This doesn't look like very clean code to me

I don't see that your typedefs add any value; instead I'd probably forward-declare SomeClass and then use 'const SomeClass&' directly.

ChrisW