开发者

why use c++ Typedef?

开发者 https://www.devze.com 2023-02-01 22:10 出处:网络
My understanding of typedef is to give a declaration an alias. Such the declaration for int will now be referred to as Integer. But why? Why would someone use typedef? What\'s the more advantage开发者

My understanding of typedef is to give a declaration an alias. Such the declaration for int will now be referred to as Integer. But why? Why would someone use typedef? What's the more advantage开发者_开发知识库ous reason?

typedef int Integer;

Integer blamo = 50;

cout << blamo << endl;


that isn't a good example because Integer and int don't have any different meaning. But imagine something like,

typedef int BlamoType;

Now, in the future when 'blamo' becomes a 64-bit integer, you can just change this typedef, and all other code stays the same.

Another reason for typedef is to shorten type names. For example instead of

boost::shared_ptr<std::map<std::wstring, std::vector<int> > > blamo1;
boost::shared_ptr<std::map<std::wstring, std::vector<int> > > blamo2;
std::vector<boost::shared_ptr<std::map<std::wstring, std::vector<int> > > > blamoList;

you can do:

typedef boost::shared_ptr<std::map<std::wstring, std::vector<int> > > BlamoType;
BlamoType blamo1;
BlamoType blamo2;
std::vector<BlamoType> blamoList;


A reason that no-one mentioned here: to write generic code. Consider an implementation of some container like std::vector. It should have a type called std::vector<T>::value_type so anyone that writes generic code could use it:

template<class Container> void f(const Container &c)
{
    typename Container::value_type v = c.back();
    // ...
}

How can you introduce such a type into your class? The only way is a typedef:

// !!!EXPOSITION ONLY!!!
template<class T> class vector
{
public:
    typedef T value_type;
    // ...
};


So you only have to type boost::shared_ptr<std::map<std::string,std::string>> once?


Another case to consider; function prototypes/pointers. Do you want to write this every time you define a method which takes a function pointer as an argument?

int Search( void* key, void* array, int len, int (*someFunc)(void*, void*) )
{
    // do stuff, call passed in function, etc.
}

I would rather do it this way

typedef int (*ComparisonFunc)(void*, void*)

int Search( void* key, void* array, int len, ComparisonFunc fn )
{
    // do stuff, call passed in function, etc.
}

Forgive the C comparison function here, the concept is applicable in C++ as well (but you wouldn't implement generics in terms of pointers to void of course)


The power of 'typedef' in C++ says:

C++ allows the definition of our own types based on other existing data types. We can do this using the keyword typedef, whose format is:

typedef existing_type new_type_name ;

where existing_type is a C++ fundamental or compound type and new_type_name is the name for the new type we are defining.

For example:

typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];

Some more detail about typedef Specifier


  • Benefits Of C++ typedef
  • Use of typedef with Class Types
  • Typedef - Wikipedia (Brief explanation)


There are at least 3 reasons why I use typedefs, most/all of which have been covered in answers already:

- simplification:

typedef int (*funcptr)(char, unsigned long);
funcptr f;  // f is a ptr to a function taking char & unsigned long, returning an int

typedef std::vector<Record> Container;
Container c;   // c is a vector of Records

- encapsulation:

typedef unsigned short int MY_COUNTER;
MY_COUNTER c;

Now if later on, I want to make MY_COUNTER bigger, I just change the typedef and all the counter-related code is updated (after a recompile). Note that if I had used unsigned short int explicitly everywhere for the counter, I'd have to go through all files, and only change the unsigned short int uses for a counter; I can't just globally replace unsigned short int in all code because I might use it for other things besides the counter.

- portability

typedef unsigned short UINT16;

Now when I go to a different platform, I just map UINT16 to something else (e.g., unsigned long) in one place (header file), but all my code still works (after a re-compilation). Almost like a "type firewall" - it prevents the platform changes from spreading into changes throughout all the code. Any developer (particularly embedded developers who are always dealing w/ code on multiple architectures & platforms) who's ever had to go through a large C or C++ codebase & change all occurrences of int to short int or whatever will relate to this.

Note that for any recent compiler, use of stdint.h is often available & a better way to approach platform portability. But I work on many systems where the compiler is older & stdint.h doesn't exist (or has to be created).


There are plenty of other good uses for typedefs, especially as you do more work with templates, but these 3 situations are some of the most common, useful and intuitive/obvious uses (at least IMO).


Well, it sure isn't to make the name more verbose.

There are three main reasons.

One, to make the name less verbose & easier to type. This benefit often comes in to play when dealing with classes and/or templates. For example, if you have a map between a string and some object, using a typedef can help by reducing constructs like this:

for( std::map<string, MyObj>::iterator it = my_map_.begin(); it != my_map_.end(); ++it )

to this:

typedef std::map<string, MyObj> MyMap;
for( MyMap::iterator it = my_map_.begin(); it != my_map_.end(); ++it )

The usefulness is proportional to how often you need to declare something of type MyObjMap. Just once? Not so useful. A thousand times? Pretty useful. It also helps to make code more clear & self-documenting, especially when you declare many objects of these types.

The second reason is also possibly an anti-reason. It is done to try to get a certain level of genericity and extensibility. This is done especially with class member types. The idea is to make your classes more generic so that when you change the types of the members, you don't have to change the calling code. But I mention that this can also be an anti-reason because people often think this has much more benefit than it actually does. Think back. How often have you really changes the type of a member from, say, an __int32 to an __int64? A couple times, maybe? Is that really enough to establish a coding pattern?

A final reason is really an extension of the first, to a degree. To provide convenient names for pointers to functions.


C++ has a very complex type system and some types can be very complex to express. typedef reduces the amount of code necessary. Typedef also allows for a user to be insulated from type changes and finally, it allows users to conform to semi-compile-time interfaces- like defining an iterator type.


Other examples where it would make sense could be to have a concise shorthand for a data type that was implemented as a pointer to struct, say.

0

精彩评论

暂无评论...
验证码 换一张
取 消