简体   繁体   中英

What is the purpose of typedefing a class in C++?

I've seen code like the following frequently in some C++ code I'm looking at:

typedef class SomeClass SomeClass;

I'm stumped as to what this actually achieves. It seems like this wouldn't change anything. What do typedef s like this do? And if this does something useful, is it worth the extra effort?

It prevents code like this from compiling:

class SomeClass { ... };
int SomeClass;

This is perfectly legal C++, though it's terrible . If you do this, then any references to a bare SomeClass refer to the variable. To refer to the class, you need to explicitly say class SomeClass at each usage. If you create a typedef :

class SomeClass { ... };
typedef class SomeClass SomeClass;
int SomeClass;

Then the compiler flags the definition of int SomeClass as an error, as it rightly should be.

See this previous answer to a related question. It's a long quote from a Dan Saks article that explains this issue as clearly as anything I've come across:

Difference between 'struct' and 'typedef struct' in C++?

The technique can prevent actual problems (though admittedly rare problems).

It's a cheap bit of insurance - it's zero cost at runtime or in code space (the only cost is the few bytes in the source file), but the protection you get is so small that it's uncommon to see someone use it consistently. I have a 'new class' snippet that includes the typedef, but if I actually code up a class from scratch without using the snippet, I almost never bother (or is it remember?) to add the typedef.

So I'd say I disagree with most of the opinions given here - it is worth putting those typedefs in, but not enough that I'd give anyone (including myself) grief about not putting them in.

I've been asked for an example of how not having a class name typedef'ed can result in unexpected behavior - here's an example lifted more or less from the Saks article:

#include <iostream>
#include <string>

using namespace std;

#if 0   // change to #if 1 to get different behavior
        // imagine that this is buried in some header
        // and even worse - it gets added to a header 
        //     during maintenance...
string foo()
{
    return "function foo... \n";
}
#endif

class foo
{
public:
    operator string() {
        return "class foo...\n";
    }
};

int main()
{
    string s = foo();

    printf( "%s\n", s.c_str());
    return 0;
}

When the function declaration is made visible, the behavior of the program silently changes because there is no name conflict between the function foo and the class foo .

However, if you include a " typedef class foo foo; " you'll get a compile time error instead of a silent difference in behavior.

Adam has supplied the correct reason for doing this, but regarding your question "Is it worth the trouble" I would give a resounding "No!". The possible problem code:

class SomeClass { ... };
int SomeClass;

will be caught when a bit later on someone says:

SomeClass sc;

Admittedly the compiler will point at the "wrong" line, but this sort of thing happens so rarely (I don't think I've ever seen it in real code) that it can't justify a forest of near superfluous typedefs.

It looks like the comment is trying to say that the typedef makes the symbol SomeClass global in a way that prevents anybody from being able to declare a local object with the same name that hides the original SomeClass.

I tried this out with VC6 (not a real C++ compiler I know, but the best I have ATM), and it doesn't seem to do much. SomeClass still gets hidden by a local declaration with the same name. Perhaps it changes the content of an error message for some compiler to make it more useful.

It looks to me like your colleague may not have fully graduated from C.

In C, if you declare struct foo {int a;}; , you don't have anything you can call just foo , but rather struct foo . Therefore, it's fairly common to typedef struct foo as foo .

This was changed in C++, for reasons that should be fairly obvious.

无论是真的破坏了编译器还是不知道他们做了什么的人,或者我认为。

I understand the concept of the different namespaces that tags and identifiers live in, but is this really even worth the trouble of typing it?

No.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM