开发者

What is the right way to typedef a type and the same type's pointer?

What is the right way to typedef a type and the same type's pointer? Here is what I mean. Should I do this:

typedef unsigned int delay;
typedef unsigned int * delayp;

Or should I do this:

typedef unsigned int delay;
typedef delay * delayp;

Or perhaps I should not typedef pointer at all and just use delay * instead of delayp everywhere I find开发者_高级运维 necessary?

Thanks, Boda Cydo.


The right way is not to do it. Hiding the fact that something is a pointer is commonly seen as bad style.


typedef unsigned int delay, *delayp;


Generally, you do the second block because you're re-using the type. For example, if delay needed to become an unsigned long, the definition of delayp wouldn't need to be modified.

That said, hiding pointers behind typedef's is usually a very bad idea. It's more acceptable for things that act like pointers, like iterators or smart pointers:

typedef std::vector<int> my_container;
typedef my_container::iterator my_iterator;

typedef some_type<blah> my_type;
typedef shared_ptr<my_type> my_shared_ptr;


typedefing raw pointer types is pointless (ha!). It doesn't provide any real abstraction (consumers must still understand that the types are pointers, and they must figure out how to parse whatever naming convention you use for the typename to determine what the pointee type is).

It's also bad form because if you have:

typedef T* T_ptr;

Then const T* foo and const T_ptr bar are two very different things. (foo is a pointer to a const T; it's a promise not to mutate the pointee through that pointer. bar is a pointer that is itself const; it can't be changed to point to something else.)

The first case (pointer-to-const) is important: it helps to enforce function contracts.

The second case is much, much less useful.

Therefore if you were to add a typedef for a pointer type, to be useful you'd need to create two:

typedef T* T_ptr;
typedef const T* const_T_ptr;

A tolerable exception is in C++ when you have smart pointer classes. In these cases, typing boost::shared_ptr<T> might be tedious enough that creating a typedef for it is a reasonable convenience.


In case of int it shouldn't make any difference, but in case of aggregate types latter approach is better, because in former case *delay isn't equivalent to delayp, and cast would be needed to use them interchangeably.

But as others mention, you better be off just with delay.


Your second form

typedef delay * delayp;
is better because if you'll want in the future to change "delay" typedef from int to something else (long, for instance), you can make this change in one place only.

hiding pointers may be useful if you want to allow yourself (in the future) to migrate to some kind of smartpointers instead of raw pointers (Your code will remain almost the same if pointer typedef is used) Otherwise, hiding pointers is unusable.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜