3

I've been reading different articles and tutorials on Header files. I understand that Headers serve for the purpose of keeping the "interface" from the implementation. ( and other things like some compile optimization )

What I still don't get, and really can't wrap my mind around it, is do you always use headers? I know you can write blocks of code within a header file itself. But that is where I get lost.

When I look at a video tutorial, people just define functions with their body within the Header file. Then a different article only defines the functions ( I guess that is the idea of an interface).

Just for now I'm making a simple class named Color. implementation:

/* 
* File:   Color.cpp
* Author: Sidar
* 
* Created on 26 december 2011, 16:02
*/

#include <stdio.h>

#include "Color.h"

Color::Color() {

 reset();
}

Color::Color(const Color& orig) {

 a = orig.a;
 r = orig.r;
 g = orig.g;
 b = orig.b;
}

void Color::reset()
{
    a = 0;
    r = 0;
    g = 0;
    b = 0;
}

 Color::Color(unsigned int r, unsigned int g, unsigned int b, unsigned int a)
 {
   this->r = r;
   this->g = g;
   this->b = b;
   this->a = a;
 }

Color::~Color() {
   r = 0;
   g = 0;
   b = 0;
 }

 //getters____________________________
 unsigned int Color::getRed() const
 {
   return r;
 }

 unsigned int Color::getBlue() const
 {
   return b;
 }

 unsigned int Color::getGreen() const
 {
    return g;
 }

 unsigned int Color::getAlpha() const
 {
   return a;
 }

 //setters____________________________

 void Color::setRed(unsigned int r)
 {
   if(r > 255)r = 255;
   if(r < 0)r = 0;

   this->r = r;
}


void Color::setGreen(unsigned int g)
{
  if(g > 255)g = 255;
  if(g < 0)g = 0;

  this->g = g;
}

 void Color::setBlue(unsigned int b)
{
   if(b > 255)b = 255;
  if(b < 0)b = 0;

  this->b = b;
}

void Color::setAlpha(unsigned int a)
{
 if(a > 255)a = 255;
 if(a < 0)a = 0;

 this->a = a;
 }

 unsigned int Color::color()
 {
   return (int)a << 24 | (int)r << 16 | (int)g << 8 | (int)b << 0;
  }

and here the header

/* 
 * File:   Color.h
 * Author: Sidar
 *
 * Created on 26 december 2011, 16:02
 */

 #ifndef COLOR_H
#define COLOR_H
#include <string>

class Color {
public:

    Color();
    Color(const Color& orig);
    Color(unsigned int r,unsigned int g,unsigned int b, unsigned int a);

    virtual ~Color();
    //____________________
    void setRed(unsigned int r);
    unsigned int getRed()const;
    //____________________  
    void setBlue(unsigned int b);
    unsigned int getBlue()const;
    //____________________
    void setGreen(unsigned int g);
    unsigned int getGreen()const;
    //____________________
    void setAlpha(unsigned int a);
    unsigned int getAlpha()const;
    //____________________
    unsigned int color();

   void reset();

private:

    unsigned int r;
    unsigned int b;
    unsigned int g;
    unsigned int a;


};

#endif  /* COLOR_H */

This code does work, I'm not getting any errors. But is this the general idea of headers and cpp files? And my second question: I read a lot that when using Templates it's easier to just implement the code within the Header I understand this(to prevent many implementations for something that is suppose to be so generic). But are there any other situations as well?

Sidar
  • 504
  • 1
  • 9
  • 28
  • On a side note, I would use the "this" pointer consistently (or not at all and make a clearer distinction between local parameters and class members). – AudioDroid Nov 28 '22 at 09:25

4 Answers4

4

You don't "always" do anything, it all depends on the circumstances, your goals, and the coding standards of your group or organization.

C++ is a very flexible language that allows things to be done and organized in many different ways.

Some reasons separate implementation files might be used:

  1. To keep the implementation separated from the interface, as you suggest

  2. To speed up compile times

  3. To handle cyclic dependencies

  4. So you can ship a binary library with only the header files and not the underlying source code

Some reasons why you might not want separate implementation files:

  1. You use templates, which "usually" have to be defined with the declarations

  2. You DON'T want the implementation separated from the interface. In many cases this makes things easier to understand as you don't have to flip back and forth between header and implementation file. This can be counterproductive if you're dealing with large classes with many methods, though.

  3. You want as much of your code to be inlined by the compiler as possible.

  4. You are creating a code library, for which you don't want the user to have to worry about building. Most of the Boost libraries are this way, where you don't have to use the Boost build system, which can be quite a chore, but instead you just include the header files in your code, and that's all you need to do to use them.


I usually begin the work on a new class by defining all of the logic within the header file. And then later when the class is complete, or when it starts to get crowded in the header file, I will start moving the logic out into a separate implementation file. This is strictly for making the most of my time, as I am able to get things done faster and with fewer bugs when I can see everything in the same file.

It should also be noted that you don't necessarily have to use header files at all. You can define some classes directly in your .cpp files. This is often done for private classes that will never be used outside of that .cpp file.

Gerald
  • 23,011
  • 10
  • 73
  • 102
  • Thank you for your reply. It makes more sense now. I guess I just have to do more C++ than Java/C# for a while to get used to it. I have to read more on those inline functions though. – Sidar Dec 26 '11 at 18:20
0

Okay first of all here is the answer of why templates can only be implemented in header files:

Why can templates only be implemented in the header file?

It is not because it's generic, it's because of the way compilers actually handle templates. If you don't get the explanation there, msg me :).

Community
  • 1
  • 1
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
0

If you put method implementations in the header file, the C++ compiler may choose to inline the code at call-sites. So it can be more efficient.

If you have a class defined fully in a header file then you don't need a .cpp file making things (if the implementation is short) a bit easier to understand.

  • But when do I want a CPP file like my given code? That is where I just hit a full stop. – Sidar Dec 26 '11 at 16:55
  • hahah, you're not making it easier for me. So there really is no standard on how to do this? The convention only exists within the groups you are working with? – Sidar Dec 26 '11 at 16:59
  • You can have the header file and binary for the cpp, you don't need the source to use it. – Steve C Dec 26 '11 at 17:13
0

Header files are not used to "separate the interface" from the implementation, they already contain many implementation details unless you use the pimpl idiom. That, is a different topic and it can be done in any language that does not have "header" file like C# and Java.

Their real use comes from the fact that when the compiler must allocate room for an instance of a class, it must know its size. To compute the size, it needs a complete declaration for that class. Since you are probably going to do use instance of that class among many translation units, the only sane way to provide that declaration is to put it in a header file and #include it when needed.

When you create a pointer to an instance (or a reference), the compiler does not need to know the size of that class since pointer have typically the same 4 or 8 byte size. For those cases you can just use a forward declaration instead of #including the header.

Now, the reason why you can include code in a header file is due to the current C++ template mecanics. That code will be compiled many times but the compiler/linker will eliminate all copies and keep a single one in the final compiled code.

Simon P.
  • 522
  • 1
  • 4
  • 7