Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly goes to a header file and what in implementation file in C++?

Tags:

c++

c++11

I have an example with the custom Stack implementation. As far as I understood, the .h files should only contain declarations and the cpp files should only contain implementations. I have found an example of a custom Stack on the cplusplus.com/stack_example and it looks something like the following.

Stack.h file

#ifndef _STACK_H_
#define _STACK_H_

#include <iostream>
#include "Exception.h"

template <class T>
class Stack {
    public:
        Stack():top(0) {
            std::cout << "In Stack constructor" << std::endl;
        }
        ~Stack() {
            std::cout << "In Stack destructor" << std::endl;
            while ( !isEmpty() ) {
                pop();
            }
            isEmpty();
        }

        void push (const T& object);
        T pop();
        const T& topElement();
        bool isEmpty();

    private:
        struct StackNode {              // linked list node
            T data;                     // data at this node
            StackNode *next;            // next node in list

            // StackNode constructor initializes both fields
            StackNode(const T& newData, StackNode *nextNode)
                : data(newData), next(nextNode) {}
        };

        // My Stack should not allow copy of entire stack
        Stack(const Stack& lhs) {}

        // My Stack should not allow assignment of one stack to another
        Stack& operator=(const Stack& rhs) {}
        StackNode *top;                 // top of stack

};

Now I have question. This .h file obviously reveals some implementation details. The constructor and the destructor are both implemented in the .h file. In my understanding, those should be implemented in .cpp file. Also, there is that struct StackNode which is also implemented in the .h file. Is that even possible to implement in the .cpp file and only declare it in the header file? As a general rule, wouldn't it be better if those were in the .cpp implementation file? What would be the best way to code this thing so that it follows C++ rules?

like image 303
Whizzil Avatar asked Oct 20 '15 10:10

Whizzil


1 Answers

Header files are not fundamentally different from source files.

A header can, in principle, contain the same code constructs that a source file can. The only thing that, by convention, distinguishes a header from a source file is that a header is supposed to be #included by other files, which we usually do not do with source files (although we could, if we felt adventurous).

The important thing now is what happens if a file gets #included by more than one source file. Mind you, this is basically equivalent to copy-pasting the same code to multiple .cpp files. There are certain things that will likely get you into trouble in this case.

In particular, if you end up with two definitions for the same symbol in two different source files, your program is not well-formed (according to the one-definition rule) and the linker will probably refuse to link your program.

With distinct source files this usually not a problem, unless you accidentally reuse a name in different contexts. As soon as header files step into the picture (which are just copy-pasted code), things start to look different. You can still put a definition in a header file, but if that header file then gets pulled in by more than one source file, you have yourself a nice violation of the one-definition-rule.

Therefore, the convention is to only put stuff into header files that is safe to be duplicated across multiple source files. This includes declarations, inline-function definitions and templates.

The key realization here is probably that header files are a rather archaic tool for sharing code between source files. As such, they rely heavily on the user being smart enough not to mess things up.

like image 144
ComicSansMS Avatar answered Sep 29 '22 08:09

ComicSansMS