8.9 — Class code and header files

Defining member functions outside the class definition

All of the classes that we have written so far have been simple enough that we have been able to implement the member functions directly inside the class definition itself. For example, here’s our ubiquitous Date class:

However, as classes get longer and more complicated, mixing the declaration and the implementation details makes the class harder to manage and work with. Using an already-written class only requires understanding its public interface (the public member functions), not how the class works underneath the hood. The implementation details just get in the way.

Fortunately, C++ provides a way to separate the declaration portion of the class from the implementation portion. This is done by defining the class member functions outside of the class declaration. To do so, simply define the member functions of the class as if they were normal functions, but prefix the class name to the function using the scope resolution operator (::) (same as for a namespace).

Here is our Date class with the Date constructor and setDate() function defined outside of the class definition. Note that the prototypes for these functions still exist inside the class declaration, but the actual implementation has been moved outside:

This is pretty straightforward. Because access functions are often only one line, they are typically left in the class definition, even though they could be moved outside.

Here is another example:


Putting class definitions in a header file

In the lesson on header files, you learned that you can put functions inside header files in order to reuse them in multiple files or even multiple projects. Classes are no different. Class declarations can be put in header files in order to facilitate reuse in multiple files or multiple projects. Traditionally, the class declaration is put in a header file of the same name as the class, and the member functions defined outside of the class are put in a .cpp file of the same name as the class.

Here’s our Date class again, broken into a .cpp and .h file:



Now any other header or code file that wants to use the Date class can simply #include "Date.h". Note that Date.cpp also needs to be compiled into any project that uses Date.h so the linker knows how Date is implemented.

You might be tempted to put both your class declaration and implementation into the header file. While this will work (and is fine for trivial classes), it is not recommended, as there are a couple of downsides. First, your class implementation code will be copied into every file that #includes it, and get recompiled there. This can be slow, and will cause bloated file sizes. Second, if you change anything about the code in the header, then you’ll need to recompile every file that includes that header. This can have a ripple effect, where one minor change causes the entire program to need to recompile (which can be slow). If you change the code in a .cpp file, only that .cpp file needs to be recompiled!

Rule: Put class declarations in a .h file, and non-trivial member function implementations in a .cpp file, both named after the class.

In future lessons, most of our classes will be defined in the .cpp file, with all the functions implemented directly in the class definition. This is just for convenience and to keep the examples short. In real projects, it is much more common for classes to be put in their own code and header files, and you should get used to doing so.

Default parameters

Default parameters for member functions should be declared in the class declaration (in the header file), where they can be seen by whomever #includes the header.


Separating the class declarations and class implementation is very common for libraries that you can use to extend your program. Throughout your programs, you’ve #included headers that belong to the standard library, such as iostream, string, vector, array, and other. Notice that you haven’t needed to add iostream.cpp, string.cpp, vector.cpp, or array.cpp into your projects. Your program needs the declarations from the header files in order for the compiler to validate you’re writing programs that are syntactically correct. However, the implementations for the classes that belong to the C++ standard library is contained in a precompiled file that is linked in at the link stage. You never see the code.

Outside of some open source software (where both .h and .cpp files are provided), most 3rd party libraries provide only header files, along with a precompiled library file. There are several reasons for this: 1) It’s faster to link a precompiled library than to recompile it every time you need it, 2) a precompiled library can be distributed once, whereas compiled code gets compiled into every executable that uses it (inflating file sizes), and 3) intellectual property reasons (you don’t want people stealing your code).

Having your own files separated into declaration (header) and implementation (code file) is not only good form, it also makes creating your own custom libraries easier. Creating your own libraries is beyond the scope of these tutorials, but separating your declaration and implementation is a prerequisite to doing so.

8.10 -- Const class objects and member functions
8.8 -- The hidden “this” pointer

67 comments to 8.9 — Class code and header files

  • Sam

    I’m having some trouble with what seems like using class in the class I’m writing.

    This is the header file:

    #ifndef GUEST_H
    #define GUEST_H

    using namespace std;

    class Guest {


    string Name, Addr1, Addr2, Phone;
    int Smoking, Pets; //0=none


    // default constructor
    Guest() ;

    // destructor
    ~Guest() ;

    //…other member functions…



    The problem is, the compiler doesn’t seem to recognize when a member function tries to use Name. I’ve tried inserting std::string instead of string for the initialization, but that didn’t seem to work.


  • Deepu

    I think thr is another advantage of seperating implementation from defention in header files and cpp files.

    Suppose you are writing a Application Programming Interface ( a DLL or .so file) which your clients would be using, you normally give them the header files and the dynamic link libraries. As long as the signature of the methods defined in the interface does not change your client can make use of your diffrent vesions of your API. Also this is a good idea as you dont need to expose your source code to your client exposing all methods available in the API and a users manual on how to use them.

  • stephen

    what is the point of constructors? they are a waste of time to me, i just allocate the variables int the class

    • The point of constructors is to initialize the members of your class when the class object is created.

      There is no other way to initialize constant members of a class, for example.

  • cpp_beginner

    It’s a good idea to put classes and other functions in header files but can we put them in a .dll file?If so,can you make a short tutorial of how to make a Dinamic Link Library in VC++ 08??

  • Phil

    I just tried writing my own Date class using separate files, but using default parameters for the constructor
    . I wasn’t sure if the default parameters should be in the date.h or date.cpp file (or both). With a little t
    rial and error, discovered that the default parameters should go in the header file only. Maybe this should b
    e mentioned in the tutorial?

    By the way - Fantastic tutorial 🙂

  • hakaye azure


    Thanks for the tutorial pages, it is magnificent.

    I have a problem over here:




    compile result an error messages:
    Unresolved external ‘mymath::~mymath()’ referenced from [folder]mymathtest.obj
    Unresolved external ‘mymath::mymath()’ referenced from [folder]mymathtest.obj
    Unresolved external ‘mymath::mult(int, int)’ referenced from [folder]mymathtest.obj

    I work around this problem for hours (not the same code but the same idea), I don’t know where the codes went wrong
    and the last trial and error solve the problem, by adding a single line at the bottom of mymath.h, but is it the right way?

    • Gammerz

      You don’t need to add that last line of code in mymath.h

      Just add mymath.cpp to your project (I believe it gets linked in). I managed to get your original code working ok like this. Alex states:-

      Note that Date.cpp also needs to be compiled into any project that uses Date.h so the linker knows how Date is implemented.

  • In the second-to-last paragraph you said :
    “simply #include “Date.h”. Note that Date.cpp also needs to be compiled into any project that uses Date.h so the linker knows how Date is implemented. ”

    but why we didn’t include the Date.cpp file and the compiler knows where it is ,and compiles it? this confuses me for long time ,(i am a new C++ learner) Thanks Alex!

    By the way ,this tutorial is excellent,master piece! I want to work with you! Hah, but now I am a Chinese live in China. I longing US badly!

    • Alex

      It’s bad form to #include a .cpp file. C++ doesn’t disallow it, and in some cases (particularly simple ones) it will work, but in many cases you’ll end up running into problems, such as naming conflicts. Particular if you both #include a .cpp from another .cpp file AND put it in your project (in which case, the code will get compiled twice).

  • Clint

    If you have two different .cpp files that both have functions that use the <string> class, do you need to #include <string> in both of them?  If so, doesn’t it make things much less efficient to have all these different files that are all pulling from outside classes?    It seems like you also need to add #include "stdfx.h" and "using namespace std" to all the .cpp files (since I am using Visual Studio).

    Would it be better to keep things in one .cpp file so that you only have to #include outside files once?  Is the guideline still "one class, one file" even if your class member functions use a bunch of other libraries?  Thank you!

    • Jiri

      I think it has no effect on speed of compiled code - all header files have header guards, there will be no duplicates. You could speed up compilation a bit for sure, but the price for it is loss of modularity - you would not be able to withdraw a singl class without rewriting its header to include what it must in new project. One file would be a mess in bigger projects, How do you want to search for something in 10 000+ lines file ? It is better to search in header names.

      • Alex

        Jiri almost gets it right. Having multiple files may have an effect on compilation speed -- header files only prevent a header file from being #included more than once into the same includer. They do not prevent a header file from being included once each into many different files. A single header file that gets #included into 5 files will get compiled 5 times.

        That said, header files are typically just declarations, which compile quickly. The runtime speed won’t be impacted. The increase in organization and modularity is worth the small compilation time cost.

  • In the first example, why you wrote a default constructor that is private and not even calling any other function to set the initial value of member variable. Isn’t it redundant? I am talking about this line:

    • Alex

      Making a default constructor private means we can’t create objects that would use the default constructor for initialization. For example:

      In this case, we’re doing that because there isn’t really any good default value we should assume if the user doesn’t provide a date.

      This, in essence, forces the user to use one of the other constructors to create the object (and thus, provide default values for the object being created).

      • How much time would it take to me to think like you… 🙂 ??? You are just awesome.

      • Mekacher Anis

        in the lesson on constructors u said that if we declare any kind of constructor the compiler won’t create a default one so there is no need to make a default constructor private , just create one with arguments and no default parameters
        am I right ?

        • Alex

          You’d only need to make the default constructor private if you didn’t have any other constructors, and didn’t want people to instantiate objects of the class without parameters.

          • Mekacher Anis

            if making it private only restricts the user from using it (but the compiler can) that would be alright , but if it restricts both of them of using it and there is no other public constructor how would it get even constructed ?

            • Alex

              Making a constructor private prevents non-class functions from using the constructor (but it could still be used by other members of the class).

              So you could do something like this:

              • Darren

                Isn’t this a catch 22? In order to get an instance of "Something" you have to call the "getSomething()" member function from an **existing** instance of "Something" - catch 22. However if you made the member function return a static reference to "Something" then you can get a single instance of the class, but only a single instance. "Something" is then said to be a Singleton class. The code for this is:
                Class definition …

                Class usage …

                This is similar to an interface method in Java, I think.

                • Alex

                  Yeah, it’s a silly example, and not at all useful. Obviously a singleton pattern makes more sense here, but I haven’t covered what static members are at this point in the tutorial series so I was trying to find an example that didn’t use static.

  • Banelus

    I’d like to know whether you recommend using include directives (e.g. #include <cstdint>, #include <iostream>) in header file with class declaration? I noticed it’s needed for std::cout, int32_t etc. What do you say?

    • Alex

      My take is that all files (whether code or header) should be responsible for #including the things that they themselves need to compile.

      For example, if a header file has an inline function that uses std::cout, that header file should definitely #include iostream.

      If a header file doesn’t use std::cout but it’s implementation file does, the implementation file should #include iostream.

      If a header file and an implementation file both use std::cout, then I typically have both #include iostream (even though the .cpp file doesn’t need to -- it will get a copy of iostream from the header). That way if the header file later changes and doesn’t need iostream any more, I don’t have to modify the implementation file, because it’s already self-sufficient.

  • Jiri

    #include <iostream>
    #include "something.h"
    #ifndef SOMETHING
    #define SOMETHING
    #include <iostream>
    #include "something.h"
    #include <iostream>

    Please correct me if i am wrong:
    - In compiled code there will be only one <iostream>, because it has header guard.
    - With prototype of every funcion i use in main.cpp i would not need any includes at all (in theory, i know its nonsense to do that)

    • Alex

      Header guards prevent a header file from being included more than once into the _same_ file. In the example above, main.cpp, something.h, and something.cpp will all have a _single_ copy of the declarations in iostream.

      Yes, if you did all of your forward declarations directly in main.cpp, you wouldn’t need to use a header, but you might as well use headers since they’re cleaner and can be shared.

  • Mr D

    I’m really failing to understand this chapter.

    I don’t understand the difference between class "definition" and "implementation".


    example is actually longer (32 lines) then the original (26 lines) and i don’t see the benefit. Are the functions that are moved outside now placed in


    To use the functionality of the class, you don’t need to look inside it at all do you? Isn’t that all done from

    I don’t see the reason to move anything outside. I thought the benefits of classes (mentioned earlier) is that they package things up nicely and keep stuff out of site, but in this lesson you’re recommending un-packaging them again!!

    Same thing with the class Calc example, the original seems nice and compact, the second version seems a lot longer and harder to read.

    I’m sure i’m just not getting something fundamental here. If possible, could you give a clear explanation of the difference between class "definitions" and "implementations"?

    • Alex

      The key passage for this lesson is this one: However, as classes get longer and more complicated, mixing the definition and the implementation details makes the class harder to manage and work with. Typically, when looking at a class definition (for an already written class), you don’t care how things are implemented -- you want to know how to use the class, which involves only its definition. In this case, all of the implementation details just get in the way.

      The benefit of classes is that they package up data and the functions that work on that data. Whether the functions are defined inside the class declaration or outside of it does not impact this.

      The original versions of the classes may seem more compact to you because the member functions are simplistic. However, in the case where the member functions become complex (imagine 100 lines each) putting all of those inside the class definition would make the definition long and complex.

      By definition, I really mean the class declaration, including the classes’s name, access specifiers, member variables, and member functions. The classes’s implementation includes the definition (body) for all the functions.

      Typically I use a mix of the two styles: If a function is only one line long, I typically keep it in the class declaration. If the function is more than one line long, I move it to the file that contains the implementation.

      There’s one other benefit to keeping your member function definitions in a separate file. If you change something in a function body, you only have to recompile that one file. If you change something in a class declaration (in a header file), you need to recompile EVERY file that #includes that header, which could be a large part of your project.

      Did this address your concern?

      • Mr D

        Thanks Alex, that helps. I’ll keep on keepin’ on!

      • Darren

        When I first came to learning classes in C++ I was initially confused about class definitions because of the overlap in language used when talking about function definitions. With functions you typically have the prototype (or declaration) in a header file (.h), with the function definition (i.e. its implementation) in a source file (.cpp). With classes you have the definition (similar to a function’s prototype) in the header file, and the class implementation in the source file. Once I got it in my head that a **class** definition is essentially its prototype, with its implementation being separate that straightened it out for me.

        Now the reason why its not called a class prototype or class declaration it because you can forward declare a class in a header file by doing

        so long as you define and implement that class elsewhere. You might want to so this if "AnotherClass" uses "MyClass" in its definition but you don’t want to #include MyClass’ header file in AnotherClass’ header file for compilation performance/order reasons.

        • Alex

          It’s not _quite_ that simple though. With a function, if you have a forward declaration, you can use that function anywhere. The compiler will be happy, and the linker will resolve the call (assuming the function is properly extern).

          However, with a class, a forward class declaration only serves to indicate that the class exists, but not anything about how it’s implemented. So if you try to do something like this:

          It won’t work, because the compiler needs to know how large A is to create a B. You can work around this by making m_a a pointer to A instead of an A, but that’s a pain.

          For the most part, class declarations aren’t that useful. The good thing is because it’s so easy to import a class definition via the class header file, there’s rarely a reason you need to forward declare classes (the exception being classes that have a circular dependency).

          • Darren

            Does the order in which files get complied have a dependency on header file inclusion order? Or is it decided by the compiler? Using Visual Studio all these considerations are dealt with for you (casual users at least), whereas using command-line gcc (or g++) on Linux tends to make you think more about these things.

            • Alex

              The order that files get compiled and linked is determined by whomever calls the compiler and linker. On the command line, that’s you, so you get to decide. With an IDE, the IDE typically generates this for you.

              I don’t have any insight into what factors Visual Studio uses in determining compilation order.

  • Paul

    In your date exmple, in the Date.h file:

    is this line considered to be a constructor? Or is it just a constructor prototype?

    Also, I guess I’m struggling with the notion of moving the implementation outside of the class. I thought that was the purpose of having the class…to access a member function in a class without worrying about how it’s implemented. It seems like if you’re going to put all the implementation into a cpp file anyways, why is a class needed? Sorry…just thinking out loud. I’m still soaking it in 😉

    • Alex

      It’s part of the class declaration. So yes, it’s a constructor prototype (that is defined in Date.cpp).

      > I thought that was the purpose of having the class…to access a member function in a class without worrying about how it’s implemented

      Depends on whether you’re writing or using the class. If you’re using the class, you don’t need to worry about how it’s implemented (same with a normal function). If you’re writing the class, you certainly do.

      The main benefit of classes is the ability to define your own custom types that both store data and provide functions that work on it. Whether the functions are defined in the class declaration or outside of it doesn’t change this.

  • Javad

    How do you forward declare a constructor with member initializer list?

    • Alex

      If you’re asking how you’d forward declare a constructor with a member initializer list default value, you’d do something like this (using a std::vector, since that supports a list initializer):

      class Whatever
      Whatever(std::vector mylist = {1, 2, 3});

      • Javad

        No that was not my question. I should have given an example to clarify my question. Here is what I mean:

        class Something
           int m_nValue;
           Something(int value) : m_nValue{value}
                std::cout << m_nValue;

        Now let’s say I want to forward declare the above constructor. How should I do this? I cannot put ‘;’ at the end of the member initializer list.

        • Alex

          You’d forward declare this constructor as “Something(int);” or “Something (int value);”.

          Initialization values are only attached to the actual constructor definition, not a forward declaration.

  • Shiv C Kushawah

    awesome learning…
    I’m infant like boy in the matter of computer programming, @(,-_-,)@ how sad…!
    please provide me a right way to start…

  • Kris

    I’m having an issue with the Date example with separated header and .cpp in my Main Function. I have the exact same .h code but here is my .cpp class:

    Whenever I try to do the commented out print statement I get the following error [‘Date::getMonth’: non-standard syntax; use ‘&’ to create a pointer to member]. I know I could just print out the int I implemented and declared from my cin line but I’m not sure why this wouldn’t work. Thanks!

    • Shiva


      This wouldn’t work because you are not creating any object of the class Date. I believe your call:

      only creates a temporary anonymous instance of Date which can’t be referenced. Change it to:

      This creates an object d of Class Date with the constructor. Then change the commented line to:

      This calls the member functions on the object d and thus prints the values of it’s member variables. It works.

      Hope that helps. 🙂

      • Kris

        I actually was able to figure it out like 20 minutes after I posted it but I didn’t understand the reason why. This helped to explain it a little better. Thanks!

    • Alex

      Date::getMonth isn’t a function call. Date::getMonth() is. C++ is confused because you’re trying to print function pointers instead of the results of a calls to functions.

  • Shiva

    Hi Alex,

    This is something I always wanted to know:
    > but prefix the class name to the function using the scope operator (::) (same as for a namespace).

    Does this mean that a class creates it’s own namespace and put its members inside it, like an enum class? Or is the :: operator overloaded to have different meanings in the cases of class, enum class and namespaces? From what I’ve learned, static members of the class are also accessed with it.

    BTW it’s called scope resolution operator, isn’t it?

    • Alex

      I’m not totally sure whether classes create their own namespaces or just act like it, but the result is the same either way, so I suppose it doesn’t really matter.

      And yes, it’s called the scope resolution operator. Thanks for pointing that out.

      • Shiva

        Hmm. I prefer to think classes create their own namespaces. That way the scope resolution operator can be assumed to have a uniform behaviour in all places. Simplifies life. 😉

        BTW you’ve called it scope operator in chapters 8.11 & 8.12 too.

        • Darren

          It is not implausible that two different developers may use the same name for a class that would have different definitions and/or implementations. If these two separate pieces of code were brought together in a single project there would be a name clash. Classes should therefore be put into their own namespace along with other code. Name clashes may still occur if those namespaces are also the same but it is far less likely that both developers will choose the same combination of namespace name and class name.

          To illustrate, let’s say you wan to create a mathematical vector class that does things like dot products, cross products, and so on. You wan to call this class “vector”, quite a sensible name. You don’t put this “vector” class inside its own namespace. You write some code where you want to store some variables in a std::vector. Because you are lazy, you put “using namespace std” somewhere convenient, say in the global namespace. You now come to try to do some stuff with your “vector” class. Oh dear what are all these compilation errors? Debug, tear hair out, debug some more, bash head against desk, debug, then spot namespace clash, grrrr!!! Avoid this by **always** placing your classes in a (approximately) unique namespace (doubly avoid by not putting a using namespace in the global namespace).

  • Vijay

    Hi Alex, I didn’t get this.

    a precompiled library can be distributed once, whereas compiled code gets compiled into every executable that uses it (inflating file sizes)

    what does this mean?

    • Alex

      A precompiled library can be turned into a standalone file that can be shared by many different executables. This means you have one copy of the library total instead of one copy of the library per executable.

  • Vijay

    Thank you Alex, where that precompiled libraries will be there? It will come when we install OS?

    • Alex

      Precompiled libraries are usually installed with the software that need them. For example, the C++ runtime is a precompiled library, so if you’re installing a program written in C++, it’ll probably install the C++ runtime library (if it’s not already installed).

  • Vijay

    Thank you very much Alex, you are doing great job. It became one of my favourite site.

  • Matt


    Under "Defining member functions outside the class definition", in your third code example, you wrote:
    "int getValue() { return value; }".

    I think "value" should be "m_value".

  • Dominik


    Great tutorial, thank you for this.

    I have always some problem to distinguish definition and declaration. In the header "Putting class definitions in a header file" shouldn’t be "declaration" instead of "definition"?

    • Alex

      I think definition is a better fit here, since you’re typically defining the full class definition in the header, not just a forward declaration.

  • Hossam

    i having some trouble
    #ifndef bst_h
    #define bst_h

    class bst
        class node
            int key;
            node* left;
            node* right;
        node* root;



    using namespace std;
    using std::string;

        root= NULL;

    error msg.
    one or more multiply defined symbols found
    please how can i solve this error

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter