How to implement a multi-file class.

Hey guys!

So I am trying to set up a very simple program that uses a class in a separate file.

Currently, I have a main.cpp, a class.cpp, and a class.h

Here is the template of my code. I included everything but the code within the functions themselves (because it would take up a lot of space and it is just couts):

Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

  #include <iostream>
#include <string>
#include "CharacterStats.h"
using namespace std;


class CombatMechanics{
    public:
        int basicAttack(){
            //code code
            return 0;
        }
};

class LocationsClass{
    public:
        void trainingRoom1(){
            //code code
        }
};

void choiceLoop(){
    for (int a = 0; a<20; a++){
        //code code
        CombatMechanics com;
        com.basicAttack();
        //code code
        }
        
    }
}

int main(){
    //code code
    choiceLoop();
    //code code
}


Characterstats.cpp (the class file)
1
2
3
4
5
6
7
8
#include <iostream>
#include <string>
#include "CharacterStats.h"
using namespace std;

CharacterStats::CharacterStats(){
    cout << "CharacterStats has begun!" << endl;
}


Characterstats.h
1
2
3
4
5
6
7
8
9
10
#ifndef CHARACTERSTATS_H
#define CHARACTERSTATS_H


class CharacterStats{
    public:
        CharacterStats();
};

#endif 


When run, I get the following error:

undefined reference to `CharacterStats::CharacterStats()'

Apparently I did not "implement" the class files.
I am not really sure what this means.

Any help appreciated!
closed account (SECMoG1T)
what do you mean by this Apparently I did not "implement" the class files.?

you need to define all functions inside your classes before you attempt to create objects which use them, the error above shows that your compiller couldn't access the definition of your CharacterStats class default constructor in one of your file, also avoid multiple inclusions so the following should work.

CharacterStats.h
1
2
3
4
5
6
7
8
9
#ifndef CHARACTERSTATS_H
#define CHARACTERSTATS_H

class CharacterStats
 {
    public:
        CharacterStats();
 };
#endif  



CharacterStats.cpp
1
2
3
4
5
6
7
8
#include <iostream>
#include <string>
#include "CharacterStats.h"
using namespace std;

CharacterStats::CharacterStats(){
    cout << "CharacterStats has begun!" << endl;
}



main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "CharacterStats.h"

class CombatMechanics
{
    public:
        int basicAttack()
        {
            //code code
            return 0;
        }
};

class LocationsClass
{
    public:
        void trainingRoom1()
       {
            //code code
        }
};

void choiceLoop()
{
    for (int a = 0; a<20; a++)
    {
        //code code
        CombatMechanics com;
        com.basicAttack();
        //code code
     }
        
}


int main()
 {
    //code code
    choiceLoop();
    //code code
}
In response to andy1992

you need to define all functions inside your classes before you attempt to create objects which use them, the error above shows that your compiller couldn't access the definition of your CharacterStats class default constructor in one of your file...

I understand what you are saying, but I am still left wondering how do I define the class?
To my knowledge, #including the header file that defines the class is sufficient. If this is false, what measure do I take to define the constructor?
http://www.cplusplus.com/forum/general/113904/
I think that the problem is that you forgot to link the file that defines the constructor (CharacterStats.cpp)
In response to ne555

<code>
I think that the problem is that you forgot to link the file that defines the constructor (CharacterStats.cpp)
</code>

Oh my! Yes this is the solution. I had this misunderstanding that only header files could be #included.
Thanks a lot!

And thanks to andy1992, this is exactly what he said, ne555 was just more specific.
> I had this misunderstanding that only header files could be #included.
you were right
if you are including a source file, you are doing something wrong.
In response to ne555,

When I #include "CharacterStats.cpp" the function ran successfully, so it fixed my problem. Is this bad code-etiquette?

And if so, then what did you mean by link the file that defines the constructor
1
2
void foo(){}
void foo(){} //error: redefinition of `void foo()' 
To #include something is equivalent to copy-paste its entire content. If you end up including the same source file twice, you'll end up with redefinition errors (it does not matter that the function implementation is exactly the same).

Another reason to not include source files is ``because it kills the purpose of having a linker. If you modify the main.cpp, you will need to recompile the included cpp files (that did not change), ending with higher compilation time''.

In conclusion, it is not bad etiquette, it is wrong.


> what did you mean by ``link the file that defines the constructor''
Sources are not transformed directly into an executable. Instead, `object files' are created from them (compilation) and then those object files are "merged" to create the executable (linking)

Your build process may end up being something like
g++ -c CharacterStats.cpp #compilation
g++ -c main.cpp #compilation
g++ CharacterStats.o main.o -o program.bin #linking
your IDE will automatize all the process, but you need to tell it which files compose your program. Create a project and add them.
Topic archived. No new replies allowed.