4

for example, I have A.h, which has a class A with some empty methods:

class A : public B{
public:
    A(){
    }

    virtual void b(){
    }

    ~A(){
    }
    //other methods
};

should I move all empty methods definition into A.cpp:

#include A.h
A::A(){
}

void A::b(){
}

A::~A(){
}

//other methods

? and which is the more recommend way?

5 Answers 5

9

Either is perfectly legal and should generate the same code with modern compilers. (For a simpleminded compiler, it might not try to inline code that isn't found in the header and generate a useless call to an empty function, but I doubt if any real compiler would be that simpleminded.) There is a tiny potential time savings at compile time if you didn't need the .cpp at all -- one less file for the compiler to open/read -- but that is really trivial. So the question really is which makes more sense to use for the humans involved.

The first rule I use is "When in Rome". If other code in the system you are working on does it one way or the other, follow that lead. Mixing styles leads to confusion, so keep it consistent.

If there is no precedent then you can do whatever you'd like. I'd personally use the inline approach when defining a base class that does nothing which you intend to be overridden by others. That makes it clear that you aren't doing anything in the base without requiring anyone to dig into the implementation.

If it is an override I'd probably put it in the .cpp file. Is there a great reason for doing this? Probably not. But it feels right to me.

P.S. You should make that destructor virtual, too!

2
  • "For a simpleminded compiler, it might not try to inline code that isn't found in the header and generate a useless call to an empty function, but I doubt if any real compiler would be that simpleminded." For source files that are compiled separately, there is no way the compiler when compiling another file would know what the function implementation in this file is (because it's not compiling it in that compilation unit), so there is no way it can know whether the implementation is empty or not, and no way it can "inline" it since it is not compiling the implementation.
    – user102008
    Aug 29, 2016 at 20:29
  • Do be so sure about that. Compilers/linkers are darn smart nowadays. Just because you mark something as inline, it might not be inlined and visa-versa. It can be darn near magic if you are working with a good compiler. It isn't easy, but walking through the generated assembly code can be kinda fun sometime and will almost certainly surprise you.
    – Steve
    Aug 31, 2016 at 0:20
5

If you're providing a header-only library, then you have no choice, and I'll not consider that further.

If the methods are necessarily empty, then defining in the header is usually fine (though it can be visual clutter; that can be avoided by defining outside the class declaration).

If the implementation may change due to future requirements, then be aware that code compiled against the earlier version will require re-compilation to get the new implementation. Unlikely to be a problem within a single build tree, but if you're providing a shared library, you'll want to avoid that, as it can introduce hard-to-diagnose problems.

If the methods are constructor, destructor, or copy/move assignment, then explicitly declaring = default may be what you want instead. There is a substantive difference between defining any an empty method and declaring as defaulted.

1
  • 1
    +1 for mentioning that it DOES matter if the method is exposed from shared library.
    – michalsrb
    Aug 29, 2016 at 17:29
0

Technically, it is all the same. The #include A.h directive basically means that the preprocessor will simply copy the contents of .h file in place of #include directive and move on.

Personally, I like to keep the declarations in .h and definitions in .cpp files. It is a nice convention and makes things more predictable.

2
  • 1
    Not quite the same. The first variant creates inline functions, the second doesn't.
    – gnasher729
    Aug 29, 2016 at 13:23
  • @gnasher729 Modern compilers ignore this totally and inline functions (or not) depending on optimization settings/issues. Sep 10, 2023 at 10:54
0

Would a user of the class care that there is an empty implementation? Is the empty implementation correct? In that case, someone who looks at the .h file to figure out the interface shouldn't be concerned with what particular implementation you have. Where do you put methods with very short implementations? Or medium sized implementations? Or long implementations? They should all be together in the same place.

If the implementation is empty because you haven't implemented it yet, then it may be appropriate to put it into the header file as a reminder.

0

As a general rule you should keep declaration in header files and definitions in cpp files. An empty definition is indeed a definition so it should go in the cpp file.

Putting definitions in header files could also lead to issues like symbol redefinitions so I definitely suggest not to do it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.