Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typedef return type in header and source files - what is best practice?

I have a class with a member function with a lengthy return type:

/* MyClass.hpp */
namespace foo 
{
  class MyClass
  {
  public:
    SomeNameSpace::Lengthy_return_type_name someFunction(params...); 
  };
}

I want to make this more readable without making things confusing for the reader, and I don't necessarily want to expose the typedef to the outside world. So in MyClass.hpp I added the following typedef within MyClass:

/* MyClass.hpp */
namespace foo 
{
  class MyClass
  {
  private:
    typedef SomeNameSpace::Lengthy_return_type_name myType;
  public:
    myType someFunction(params...); 
  };
}

Now, in MyClass.cpp I have a dilemma because myType is not visible to be able to use as a return type. I could use MyClass::myType if I made the typedef public, but I don't like that since I think it is confusing and also exposes myType. I could also add the typedef to the top of MyClass.cpp, but this might take away from the meaning since readers would have to do a little digging to find out what the type is referring to.

Am I overthinking this? What is best practice in this case?

like image 449
codemonkey789 Avatar asked Oct 09 '20 06:10

codemonkey789


People also ask

What is the difference between source file and header file?

Usually, header files contain declarations, source files contain code. So, if in source file A.c you need a function implemented in source file B.c , you just include B.h to have its declaration.

Is typedef local?

typedef s are always "local to a file". So it is not exactly clear what you mean by "making it local to a file". Typedef does not introduce an entity with its own linkage, it simply creates an alias to an existing type.

What is typedef in C with example?

C - typedef. The C programming language provides a keyword called typedef, which you can use to give a type a new name. Following is an example to define a term BYTE for one-byte numbers −. After this type definition, the identifier BYTE can be used as an abbreviation for the type unsigned char, for example..

How to move a typedef to the header file?

Either you will have to take the typedef out of struct node declaration and move it to the header file, or you move the whole typedef + structure declaration to the header file. The former solution is generally what you want, since it allows you to have some information hiding. So, my suggestion is to write this in the header file:

What should be in a header file?

In my view, a header file should have the minimum practical interface to a corresponding .c or .cpp. The interface can include #defines, class, typedef, struct definitions, function prototypes, and less preferred, extern definitions for global variables.

What is the Content-Type header?

Last Updated : 29 Jul, 2021 The Content-Type header is used to indicate the media type of the resource. The media type is a string sent along with the file indicating the format of the file. For example, for image file its media type will be like image/png or image/jpg, etc.


3 Answers

The short answer is: Make the alias public. There is no reason to make it private.

For illustration I take your example one step further. Suppose myType is not just an alias but a new type:

struct foo {
    private:
       struct myType {};
    public:
       myType someFunction();
};

Now lets see what this brings: Is myType really private? No.

A caller can do

 foo f;
 auto x = f.someFunction();
 using myMyType = decltype(x);

Tada, the user has an alias for myType called myMyType. The return type of a public function is not private! Only the name foo::myType is private, but types being referd to by different names is common. There is no point in trying to hide that name. The only thing you achieve is to force the user to use a different name.

Also consider that one might expect the definition

 foo::myType foo::someFunction() {}

to fail to compile, because foo::myType is defined in the private section of foo. Though, return types of public methods cannot be really private. If the above definition was not allowed you could write:

 decltype( declval<foo>().someFunction() ) foo::someFunction() {}

So there would be really no point in disallowing the above definition.

Live example

like image 89
463035818_is_not_a_number Avatar answered Nov 08 '22 21:11

463035818_is_not_a_number


Definitely overthinking, because your callers need to have full definition available anyway. No point in restricting access to something they have to know.

Besides, what's the point in hiding a typedef from callers when it is used as a return type? It doesn't buy you anything, there's no encapsulation involved in this particular case.

Lastly, may I recommend switching to modern syntax for doing the same thing?

using myType = SomeNameSpace::Lengthy_return_type_name;

You will eventually come to love this, since it offers so much more than plain typedefs, e.g. alias templates.

like image 21
Tanveer Badar Avatar answered Nov 08 '22 23:11

Tanveer Badar


That's a good idea to define all types at the beginning.

Just have a look at any class implementation of the Standard Library: vector by example. The "Member type section" is filled by useful typedefs.

If you look at the implementation details, the general scheme is:

template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{

  typedef _Vector_base<_Tp, _Alloc>         _Base;
  typedef typename _Base::_Tp_alloc_type    _Tp_alloc_type;
  // ...

public:
  typedef _Tp value_type;
  typedef __gnu_cxx::__normal_iterator<pointer, vector>  iterator;
  typedef __gnu_cxx::__normal_iterator<const_pointer, vector> const_iterator;
  // ...

public:
  iterator begin();
  const_iterator begin() const;
  // ...
};

If the method is public you should declare the typedef to be public too. Just stay coherent and consistent.


As mentioned by others and since C++11, it is better to use using instead of typedef, see What is the difference between 'typedef' and 'using' in C++11?

like image 28
Picaud Vincent Avatar answered Nov 08 '22 21:11

Picaud Vincent