Separating Class Code into a Header and Cpp File

Separating class code into a header and cpp file

The class declaration goes into the header file. It is important that you add the #ifndef include guards. Most compilers now also support #pragma once. Also I have omitted the private, by default C++ class members are private.

// A2DD.h
#ifndef A2DD_H
#define A2DD_H

class A2DD
{
int gx;
int gy;

public:
A2DD(int x,int y);
int getSum();

};

#endif

and the implementation goes in the CPP file:

// A2DD.cpp
#include "A2DD.h"

A2DD::A2DD(int x,int y)
{
gx = x;
gy = y;
}

int A2DD::getSum()
{
return gx + gy;
}


When to separate a small class into header and cpp files?

  1. Is it reasonable to put declaration and implementation of a small class in a single file?

Yes, it is reasonable to put declaration and implementation of a small class in a single file.

If not, why not?

Because if the function definitions are modified, then all translation units which depend on the class definition need to be recompiled - or rather, all translation units which include the definition need to be recompiled. This includes all the ones that do depend on the class as they must include the definition, but also those which include the definition gratuitously.


  1. How large does a class need to be before it's better to separate into 2 files?

There is no hard limit. It depends on many variables, and is heavily influenced by personal preference.

Some people put all member function definitions in one translation unit per each class, because that's the way they know how things are done, or because they have a coding standard that must be followed.

Others swear that they cannot live without optimisation possibilities allowed by defining all functions inline in headers so that there is just one translation unit for the entire program. This also has the effect of reducing compilation time from scratch, but also causing the entire project to rebuild upon any change.

But there is no need to dogmatically follow either of these paths, and neither is necessarily optimal - both have drawbacks and advantages. So, a good choice is probably somewhere between these paths. But as I said above, the choice depends on many variables, so it's probably better to use a quick heuristic rather than full analysis. Here are a few, that you can follow if you find the reasoning suitable:

  • If the function definition is empty, then it is a very good candidate for inline definition.
  • If the function, or the class are templates, then you have to define it inline - you have no option (unless you can limit the number of possible template instantiations).
  • If definition of the function depends on definitions that the definition of the class otherwise doesn't depend on. If you define the function inline, then you cause the dependency to propagate. In this case, it is a very good idea to not define the function inline.
  • If you are in the habit of modifying the definition of the function more than extremely rarely, and the definition is used in many translation units, then it is probably a good idea to not define the function inline, or else you might find yourself recompiling the most of project again and again. This heuristic doesn't matter if the project is small and thus fast to compile in full. Also, the number of places where a class is used is often hard to track, so it is often simpler to assume the worst.
  • If you profile the program and find a particular function to be called a million times a second, then it is a good candidate for inline definition to take advantage of inline expansion optimisation. Note that using link time optimisation may allow the inline expansion even if the function is defined in separate translation unit.
  • If a function is slow to compile, then it is a good idea to not define it inline. Now, knowing which functions are slow to compile is not exactly easy to figure out, so you need a set of heuristics for this as well. Here are a few, that you can follow if you find the reasoning suitable:

    • Longer function definitions are typically slower to compile than short ones.
    • Functions which instantiate templates can sometimes be quite slow to compile.

Assuming a class is only instantiated once in the program

The number of instantiations is mostly irrelevant to the choice - other than inlining the constructor is probably not important for performance in this case.


P.S.

While it is quite portable, #pragma once is non-standard. I'm not saying you should get rid of it; this is just something to be aware of.

GetTickCount64 is system specific and non-portable. C++ has a standard clock API in the <chrono> header.

Implementation of a class into a header file and .cpp file

This would be the correct syntax. This needs to be placed outside of main():

cVector::cVector(float x, float y, float z) { // Constructor with parameters
Xpos = x;
Ypos = y;
Zpos = z;
}

Can I split my code into header and cpp files at the end of development?

Declaring and coding everything on cpp files will cause error lnk2005. Putting it all in the header file won't cause the error, although this is also against best practices. But it all depends on personal writing style.In addition, code should be easier for others to read and understand. And It's a good choice to follow experienced people's coding style.

Simple Class and Header in Separate File Won't Work

You error doesn't come up because you've used different files, so I have used one in this example

struct Foo
{
int a;
Foo()
{
std::cout << "Constructor called!";
}
};

int main()
{
Foo obj();
}

Why don't you see the message? You can read this thread

The problem here is, Foo obj() is taken as a function declaration. To fix this you need to remove the ()

int main()
{
Foo obj;
}

Constructor called!



Related Topics



Leave a reply



Submit