191

I am confused on how to separate implementation and declarations code of a simple class into a new header and cpp file. For example, how would I separate the code for the following class?

class A2DD
{
  private:
  int gx;
  int gy;

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

  int getSum()
  {
    return gx + gy;
  }
};
Sam
  • 6,961
  • 15
  • 44
  • 63
drdrdr
  • 2,248
  • 4
  • 14
  • 16
  • 13
    Just a couple of comments: The constructor should always use an initialization list instead of setting the members in the body. For a good and simple explanation, see: http://www.codeguru.com/forum/showthread.php?t=464084 It is also, at least most places, customary to have the public field at the top. It won't affect anything, but since the public fields is the documentation of your class, it makes sense to have that at the top. – martiert Mar 06 '12 at 08:14
  • 2
    @martiert Having `public:` members at the top _could_ affect a _lot_, if the user moved them according to this advice - but had ordering dependencies between members and wasn't yet aware that members are initialised in the order of their declaration ;-) – underscore_d Apr 16 '16 at 15:00
  • 1
    @underscore_d that is true. But then again, we're all compiling with warnings as errors and all the warning we can think of, right? That would at least tell you that you're screwing this up, but yeah, people use way to little warnings, and just ignore them :( – martiert Apr 19 '16 at 07:58
  • @martiert Good point, kinda forgot that generates warnings - if only warnings were read by most :-) I use them and try to code them all away. A few are unavoidable - so I say 'thanks for the warning, but I know what I'm doing!' - but most are best fixed to avoid confusion later. – underscore_d Apr 20 '16 at 16:05
  • Having public fields at the top is just a style, that too many has adopted unfortunately in my opinion. Additionally, you need to keep some things in mind as @martiert mentioned. – Vassilis May 07 '20 at 11:45

8 Answers8

265

The class declaration goes into the header file. It is important that you add the #ifndef include guards, or if you are on a MS platform you also can use #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;
}
martijnn2008
  • 3,236
  • 3
  • 27
  • 38
Ferenc Deak
  • 30,889
  • 14
  • 82
  • 151
  • 61
    Remember that if you are doing template programming, then you have to keep everything in the .h file so that the compiler will instantiate the right code at the moment of compilation. – linello Mar 06 '12 at 08:14
  • im getting an error with a duplicate symbol im not sure how to slove it .ld: duplicate symbol A2DD::A2DD(int, int)in ./src/rstring.o and ./src/A2DD.o for architecture x86_64 – drdrdr Mar 06 '12 at 08:21
  • 2
    do you have the `#ifndef` stuff in the header? – Ferenc Deak Mar 06 '12 at 08:24
  • doh. i was importing the "A2DD.cpp" instead of "A2DD.h" that fixed the duplicate symbol problem. – drdrdr Mar 06 '12 at 08:29
  • 4
    So this means that all files that include your header file will "see" the private members. If for example you want to publish a lib and its header, you have to show the private members of the class? – Gauthier Oct 23 '13 at 07:56
  • 1
    No, there is the wonderful private implementation idiom: http://en.wikipedia.org/wiki/Opaque_pointer You can use it to hide the implementation details. – Ferenc Deak Oct 23 '13 at 10:58
  • @Gauthier: Technically: yes. However, by moving the privates to another class, you don't necessarily have to share _that_ class publicly. fritzone's link shows how to do that. – Mooing Duck Sep 03 '14 at 18:38
  • 1
    linello: If I would have seen your comment before.... I've lost some hours with that issue, until I just tried copying the cpp code below the header file and it all worked... actually you can separate those files if you include the cpp at the end of the .h file just before the #endif – HoNgOuRu Apr 23 '15 at 05:19
  • @linello only if the template is instantiated in other translation units. E.g. a template private method can be defined in the `.cpp` with no problem – Caleth Sep 08 '17 at 12:04
  • How to use `this` word in the .cpp file using this separation approach? – Mohammed Noureldin Feb 20 '19 at 14:08
  • 4
    Minor nitpick with the wording: "The class declaration goes into the header file". This is indeed a declaration, but it's also a definition, but as the latter includes the former I'd rather say that the class definition goes into the header file. In the translation unit, you have the definition of the member functions, not the definition of the class. I you agree, this might be worth a small edit? – lubgr Jul 08 '19 at 07:26
  • does `#pragma once` only apply for MS environments? I thought most compiler support it already – moatze Nov 14 '19 at 10:14
  • @moatze #pragma once is not ms specific g++ has it at least from 2017,that's enough for me to down vote this answer – Spyros Mourelatos Mar 24 '20 at 12:33
  • @SpyrosMourelatos GCC supports `#pragma once` since 2013, when GCC 3.4 was released, but since it is not standardized (regardless that it is widely supported as per https://en.wikipedia.org/wiki/Pragma_once#Portability) I don't think this provides anyone a reasonable motive to downvote an answer. – Ferenc Deak Mar 24 '20 at 14:25
  • @Ferenc Deak OK fair is fair I didn't know it wasn't standard(even though it technically is) I guess I was overhyped with these feature like crazy ,but the guy seems to claim that it's a ms only feature – Spyros Mourelatos Mar 24 '20 at 17:16
21

In general your .h contains the class defition, which is all your data and all your method declarations. Like this in your case:

A2DD.h:

class A2DD
{
  private:
  int gx;
  int gy;

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

And then your .cpp contains the implementations of the methods like this:

A2DD.cpp:

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

int A2DD::getSum()
{
  return gx + gy;
}
Nick
  • 599
  • 2
  • 8
10

It's important to point out to readers stumbling upon this question when researching the subject in a broader fashion that the accepted answer's procedure is not required in the case you just want to split your project into files. It's only needed when you need multiple implementations of single classes. If your implementation per class is one, just one header file for each is enough.

Hence, from the accepted answer's example only this part is needed:

#ifndef MYHEADER_H
#define MYHEADER_H

//Class goes here, full declaration AND implementation

#endif

The #ifndef etc. preprocessor definitions allow it to be used multiple times.

PS. The topic becomes clearer once you realize C/C++ is 'dumb' and #include is merely a way to say "dump this text at this spot".

j riv
  • 3,289
  • 6
  • 35
  • 53
  • could you do this by putting the "split" files in `.cpp`, or is only `.h` really "good" for this method of code organization? – Benny Jobigan Feb 24 '19 at 23:11
  • 2
    I thought that some projects split header and (single) implementation files so that they could distribute the header files easily without revealing the source code of the implementations. – Carl G Feb 05 '20 at 06:01
  • I'm so glad you pointed this out because I originally learned on C++ then switched to C# many years ago and have recently been doing a lot of C++ again and I forgot how tedious and annoying splitting the files up is and just started putting everything in the headers .I was searching around looking for anyone giving good reasons NOT to do that when I found this. @CarlG has a good point, but other than that scenario I think doing it all inline is the way to go. – Peter Moore Jul 08 '20 at 16:52
7

Basically a modified syntax of function declaration/definitions:

a2dd.h

class A2DD
{
private:
  int gx;
  int gy;

public:
  A2DD(int x,int y);

  int getSum();
};

a2dd.cpp

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

int A2DD::getSum()
{
  return gx + gy;
}
Matthew D. Scholefield
  • 2,033
  • 2
  • 23
  • 38
Corbin
  • 31,183
  • 6
  • 65
  • 77
5

A2DD.h

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y);

  int getSum();
};

A2DD.cpp

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

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

The idea is to keep all function signatures and members in the header file.
This will allow other project files to see how the class looks like without having to know the implementation.

And besides that, you can then include other header files in the implementation instead of the header. This is important because whichever headers are included in your header file will be included (inherited) in any other file that includes your header file.

Yochai Timmer
  • 44,746
  • 21
  • 135
  • 179
4

You leave the declarations in the header file:

class A2DD
{
  private:
  int gx;
  int gy;

  public:
    A2DD(int x,int y); // leave the declarations here
    int getSum();
};

And put the definitions in the implementation file.

A2DD::A2DD(int x,int y) // prefix the definitions with the class name
{
  gx = x;
  gy = y;
}

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

You could mix the two (leave getSum() definition in the header for instance). This is useful since it gives the compiler a better chance at inlining for example. But it also means that changing the implementation (if left in the header) could trigger a rebuild of all the other files that include the header.

Note that for templates, you need to keep it all in the headers.

Mat
  • 188,820
  • 38
  • 367
  • 383
  • 1
    Putting private members and functions in the header file is not considered leaking implementation details? – Jason Sep 15 '16 at 22:46
  • 1
    @Jason, sort of. Those are *necessary* implementation details. E.g., I have to know how much space a class will consume on the stack. Function implementations are not necessary for other compilation units. – Paul Draper Sep 17 '16 at 22:53
1

Usually you put only declarations and really short inline functions in the header file:

For instance:

class A {
 public:
  A(); // only declaration in the .h unless only a short initialization list is used.

  inline int GetA() const {
    return a_;
  }

  void DoSomethingCoplex(); // only declaration
  private:
   int a_;
 };
Ivaylo Strandjev
  • 64,309
  • 15
  • 111
  • 164
0

I won't refer too your example as it is quite simple for a general answer (for example it doesn't contain templated functions ,which force you to implement them on the header) , what I follow as a rule of thumb is the pimpl idiom

It has quite some benefits as you get faster compilation times and the syntactic sugar :

class->member instead of class.member

The only drawback is the extra pointer you pay.