What is the correct way to typedef a type and a pointer of the same type?

What is the correct way to typedef a type and a pointer of the same type? 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 maybe I shouldn't point to a typedef pointer at all and just use delay * instead of delayp wherever I find it necessary?

Thanks, Boda Sido.

+4
source share
6 answers

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

+26
source

typedef unsigned int delay, * delayp;

+3
source

typedef Raw pointer types are meaningless (ha!). It does not provide any real abstraction (consumers should still understand that types are pointers, and they must figure out how to parse any naming convention you use for the type name to determine what the destination type is).

This is also a bad form, because if you have:

 typedef T* T_ptr; 

Then const T* foo and const T_ptr bar are two different things. ( foo is a pointer to const T , the promise is not to mutate the pointer through this pointer. bar is a pointer that is const , it cannot be changed to point to something else.)

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

The second case is much, much less useful.

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

 typedef T* T_ptr; typedef const T* const_T_ptr; 

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

+3
source

Typically, you make a second block because you are reusing this type. For example, if delay needs to become an unsigned long , the definition of delayp will not need to be changed.

However, hidden pointers behind typedef are usually very bad ideas. This is more acceptable for things that act as pointers, such as 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; 
+2
source

In the case of int this should not make any difference, but in the case of aggregate types, the latter approach is better, because in the previous case *delay not equivalent to delayp , and casting was necessary to use them interchangeably.

But, as others mention, you better disconnect only with delay .

0
source

Your second form

  typedef delay * delayp; 
better, because if you want to change the โ€œdelayโ€ of typedef from int to something else in the future (for example, for a long time), you can make this change only in one place.

hiding pointers can be useful if you want to allow yourself (in the future) to switch to some kind of smart controllers instead of raw pointers (your code will remain almost the same if a typedef pointer is used) Otherwise, hiding pointers are unusable.

0
source

All Articles