Undefined reference errors

Hey,

I'm getting some simple errors, and was wondering if someone could help me out. I've also got a question about header files. When and where should they be included. Should I include every needed header file in every header file that will access them?

I'm using Code::Blocks

The errors I'm getting are:

obj\Release\main.o:main.cpp:(.text.startup+0xcf)||undefined reference to `character::setname(std::string)'|

obj\Release\main.o:main.cpp:(.text.startup+0xfb)||undefined reference to `character::getname()'|

||error: ld returned 1 exit status|

character.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  #ifndef CHARACTER_H
#define CHARACTER_H
#include <iostream>
#include <string.h>

using namespace std;

class character
{
    public:
        character();
        virtual ~character();
        inline void setname(string name);
        inline string getname();
    protected:

    private:
        string name;

};


character.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
#include "character.h"
#include "string.h"
#include <iostream>

character::character()
{
    //ctor
}

character::~character()
{
    //dtor
}

inline void character::setname(string val)
{

    name = val;

}

inline string character::getname()
{
    return name;
}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <math.h>
#include <string.h>
#include <character.h>

using namespace std;

int main()
{
    string command;

    character hero;
    cin >> command;
    hero.setname(command);
    cout << "Hero's name: " << hero.getname();
    cin.get();

}
Last edited on
Did you add the character.cpp to your project?

I've also got a question about header files. When and where should they be included.

You should only #include header files that are required to build the file.

For example your character.h file should not be including <iostream> since the header doesn't use that header. Your character.cpp file should only #include character.h and <string>. And be aware of the fact that <string> and <string.h> are for different subsystems. The <string> header defines the C++ string class, where the <string.h> defines functions used with C style strings. Your main.cpp should #include <string> <iostream> and "character.h", no need for <math.h> and note that in C++ if you did require the math functions you should be using <cmath> not <math.h>.



Thanks, I've cleaned up the code as suggested, but not sure how to add character.cpp to the project. In Code::Blocks it's in the source folder. I read never to include a cpp file in another file, so put character.h at the top of main.cpp. How do you add a source file to the project other than placing it in the source folder? I had gone through file > new class.

I'm still getting the same errors.

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <cmath>
#include <character.h>

using namespace std;

int main()
{
    string command;

    character hero;
    cin >> command;
    hero.setname(command);
    cout << "Hero's name: " << hero.getname();
    cin.get();

}


character.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef CHARACTER_H
#define CHARACTER_H
#include <string>

using namespace std;

class character
{
    public:
        character();
        virtual ~character();
        inline void setname(string name);
        inline string getname();
    protected:

    private:
        string name;

};

#endif // CHARACTER_H


character.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
#include "character.h"
#include "string"

character::character()
{
    //ctor
}

character::~character()
{
    //dtor
}

inline void character::setname(string val)
{

    name = val;

}

inline string character::getname()
{
    return name;
}

Last edited on
How do you add a source file to the project other than placing it in the source folder? I had gone through file > new class.

When you created the new class did you add the class to the project, there should have been a dialog asking if you wanted to add the files to your project, you should have said yes.

Under the project menu click "Add Files" then find, select and add your file to the project. I would make sure your header file also shows up in the Management window (Projects) tab.

By the way you should also be using const qualifiers in a couple of your functions.
1
2
3
4
5
6
7
8
9
10
11
inline void character::setname(const std::string& val) // Note the const string reference.
{

    name = val;

}

inline string character::getname() const    // Note the const qualifier.
{
    return name;
}

And remember you'll need to make these changes in both the class definition and the implementations.



Last edited on
It's all there.

Management
Sources
src
-> character.cpp
-> main.cpp
Headers
Includes
-> character.h

main.cpp is in Sources, and character.cpp is in src
Last edited on
hey, character.h wasn't linked or built.

1 error left.

||error: ld returned 1 exit status|
hey, character.h wasn't linked or built.

That's good, #include files are not supposed to be linked or built, they're included, which means that they're basically copied into the the file that includes them.


1 error left.

||error: ld returned 1 exit status|

You'll need to post the complete error messages, all of them exactly as they appear in your development environment.

By the way why the "inline" qualifier on your functions?
In main.cpp change
#include <character.h>
into
#include "character.h"

In character.h remove all the “inline”.

In character.cpp change
#include "string"
into
#include <string>
Remove all the “inline”.

About ‘inline’, this is a well done explanation:
https://isocpp.org/wiki/faq/inline-functions#inline-member-fns
@JeremyBenson11

Just so you know, C++ system header files such as string has the angle brackets, and no .h extension:

#include <string>

Header files that one creates themselves are in double quotes, and normally does have an extension:

#include "character.h"

The double quotes tell the compiler to look for the file in a short list of possible locations (starting with the current directory), while the angle brackets tells it to look in standard locations for system include files.

Perhaps character is not a good name for that file and it's class. Sure it's a character in the game, but I think you could come up with a more meaningful name that that.

A convention that I personally like, is to name cpp header files with the .hpp extension: it means a header file with cpp code inside, as opposed to .h which may be implied as meaning C code. It's just a convention, a lot of people don't do it, but I find it meaningful.

There is another way of setting member variables initially: use a constructor. The purpose of a constructor is exactly that. Keep your existing constructor, add another which takes the arguments which will be assigned to all the member variables. Rather that assign the values, use a member initalization list:

1
2
3
4
5
6
character::character(const std::string& nameArg)
      :   // colon introduces member initalization list
      name(nameArg) // direct initialization, if there are more than 1 variable separate them by commas, put 1 per line
{
   // do validation here, if required
}


The reason for doing this is here:
https://isocpp.org/wiki/faq/ctors#init-lists

Another concept is when to have get and set functions. One should try to avoid falling into blindly making get and set functions for every member variable. One only need set functions if the values are going to change after construction. Even then it may be possible to have one function that sets several tightly related member variables. For example, say we have a class which represents a Triangle shape. Instead of having a variable for each vertex and functions to set and get each one (6 functions in all), have an array of 3 points, then a function which takes a Point and a position in the array to set it, another to do the same for getting a value. Also one that sets all 3 at once, and its corresponding accessor function (4 functions in all).

Good Luck !!
Topic archived. No new replies allowed.