Is there any difference between the ways to declare classes in C ++?

6

Since I started learning C ++ I've always done something like:

class.h

#ifndef CLASSE_H
#define CLASSE_H

class OutraClasse;

class Classe
{
   public:
      Classe();
      void foo(OutraClasse *bar);
};

#endif

And here I declare methods, constructor and other things classe.cpp :

#include "classe.h"
#include <OutraClasse>

Classe::Classe()
{
    //Algo aqui
}

void Classe::foo(OutraClasse *foo) {
    //Algo aqui
}

But note that eventually some classes are only written in .h like this:

#ifndef CLASSE_H
#define CLASSE_H

#include <OutraClasse>

class Classe : public OutraClasse
{
   public:
       Classe() {
           //Algo aqui
       }

       void foo(OutraClasse *bar) {
           //Algo aqui
       }
};

#endif

main.cpp would look something like both:

#include "classe.h"
#include <OutraClasse>

int main()
{
    OutraClasse outra;

    Classe foobar;
    foobar.foo(&outra);
}

I'd like to know if this influences compilation or post-compilation, for example running, this is because of the declaration order of the headers , I mean, if I understood correctly the first example I mentioned works great would only call OutraClasse when foobar is used, in the second example it would be called at all times.

Is there a difference for compilation, performance or performance?

    
asked by anonymous 05.10.2016 / 20:07

2 answers

6

Put everything in header

The great advantage is to allow better optimizations. If you want inline implementations you have to do this. The same goes for using templates that there is always an inline of the template, it is never solved at runtime. I'm talking about this in another question .

Being inline compels all consumers to recompile every time they change something in the class. This is good or bad depending on what you want.

It has a clear drawback. All class code will always have to be recompiled when this class is used (it may even be possible to have some cache that helps). There is the higher compilation cost in this case.

If the optimization is done there will be no indirection whatsoever. Performance tends to be slightly better. This often makes sense in codes that need high performance. It does not help much in GUI, for example.

Have the implementation in separate file

The big advantage is not having to compile the algorithm every time you use it, it gets separated from the declaration. In compensation you will have to recompile the algorithm file whenever you change it to the rest of the code to see. If you forget to do this, in theory everything will work, but you will access the old version, which is not what you want, can go unnoticed.

The advantage is not only the reduced compilation cost, but it has a different semantics in code modifications. While it is a disadvantage to have to recompile the implementation for consumers to see, consumers need not be aware of the change in implementation. You can recompile the class without requiring recompilation of your consumers as long as the API stays the same. The API is what is in the header.

These codes can not be optimized by inline at the places of their use. There will always be an indirection, like any non-linearized function.

This is the most common option in most cases, but the other is well used as well. You have to master the implications well to make the right choice, but in doubt the standard is this, everyone is well accustomed to it (I'm not saying it's the best always, only that's the most acceptable when you do not know what to do and the other is not required).

There's another question that might be helpful .

    
05.10.2016 / 21:25
4

Methods defined in the class declaration are automatically considered "inline" by the compiler.

The compiler can generate "inline" code for these methods, that is, a function is not created that encapsulates this code, and in each method call the code is copied instead of the method call, instead of actually being made a call to the method. Effectively an inline function is like an intelligent macro.

In principle the compiler only creates inline code for very small functions, but this is entirely at the discretion of the compiler, which may eventually simply disregard this possibility, and actually create functions to implement all inline methods.

class Classe : public OutraClasse
{
   public:
   Classe() {
       //Algo aqui
   }

   void foo(OutraClasse *bar) {
       //Algo aqui
   }
};
    
05.10.2016 / 20:54