Thread: Classes in header files - compile-time errors.

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    33

    Classes in header files - compile-time errors.

    Hi guys,

    I'm very new to C++, although have some experience in Java.
    Anyway, I'm currently learning about separating code through header files (for class declarations) and storing the definitions in .cpp files which is simple enough.

    However, the code I have been given does not compile and I can't figure out why.

    I use two files, Person.h and Person.cpp (neither is the driver for my "program", but before I even create the driver .cpp file, I can't get Person.cpp to compile)

    Person.h:

    Code:
    #ifndef PERSON_H
    #define PERSON_H
    
    class Person{
    
             private:
               string name;
               char sex;
               int age;
          
             public:
               Person(string name, char sex, int age);
               Person();
               string getName();
               char getSex();
               int getAge();
               void setAge(int age);
    
    };
    #endif
    And now the corresponding Person.cpp:

    Code:
    #include "Person.h"
    #include <string>
    
    Person::Person(string name, char sex, int age)
    {
            this->name = name;
            this->sex = sex;
            setAge(age);
    }
    Person::Person(){ name = "Default Name"; setAge(0); }
    
    string Person::getName(){ return name; }
    char Person::getSex() { return sex; }
    int Person::getAge() { return age; }
    void Person::setAge() { this->age = age; }
    This is pretty simple stuff and our tutor gave it to us, however in this current form it does not compile, and I can't figure out why.. Any ideas?

    Cheers.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If it didn't compile, then it told you why it didn't compile. If you want us to help, you'll tell us.

  3. #3
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    It will probably be something like "string is not a type" or "expected type name before string".

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Your Person class has a member variable named name that is of type string. This type is presumably intended to be std::string. As such, you should write:
    Code:
    #ifndef PERSON_H
    #define PERSON_H
    
    #include <string>
    
    class Person {
    public:
        Person(const std::string& name, char sex, int age);
        Person();
        std::string getName() const;
        char getSex() const;
        int getAge() const;
        void setAge(int age);
    private:
        std::string name;
        char sex;
        int age;
    };
    
    #endif
    Notice that I included the <string> header and changed each use of string to std::string. Notice also that I used pass by (const) reference for the name parameter in the first constructor. I also added the const keyword to the various getter functions to declare that those functions can be used even on an object of the Person class that is constant.

    As a matter of commonly used style, I also ordered the public and private sections such that the public section comes first. One reason behind this style is that while every user of the class would be interested in the public interface of the class, normally only the class maintainer would be interested in the private implementation detail of the class.

    Note that you can continue using std::string instead of string in Person.cpp, but you might also want to use a using directive (using namespace std; ) or using declaration (using std::string; ) there so as to be able to just use string instead of std::string.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Aug 2008
    Posts
    33
    Yeah sorry, should have included the error message:

    'string' does not name a type
    expected ')' before 'name'

    In constructor 'Person::Person()' :
    'name' was not declared in this scope
    At global scope:
    'string' does not name a type.

    There were one or two more, but they again mention 'string' not having a type..

  6. #6
    Registered User
    Join Date
    Aug 2008
    Posts
    33
    Quote Originally Posted by laserlight View Post
    Your Person class has a member variable named name that is of type string. This type is presumably intended to be std::string. As such, you should write:
    Code:
    #ifndef PERSON_H
    #define PERSON_H
    
    #include <string>
    
    class Person {
    public:
        Person(const std::string& name, char sex, int age);
        Person();
        std::string getName() const;
        char getSex() const;
        int getAge() const;
        void setAge(int age);
    private:
        std::string name;
        char sex;
        int age;
    };
    
    #endif
    Notice that I included the <string> header and changed each use of string to std::string. Notice also that I used pass by (const) reference for the name parameter in the first constructor. I also added the const keyword to the various getter functions to declare that those functions can be used even on an object of the Person class that is constant.

    As a matter of commonly used style, I also ordered the public and private sections such that the public section comes first. One reason behind this style is that while every user of the class would be interested in the public interface of the class, normally only the class maintainer would be interested in the private implementation detail of the class.

    Note that you can continue using std::string instead of string in Person.cpp, but you might also want to use a using directive (using namespace std; ) or using declaration (using std::string; ) there so as to be able to just use string instead of std::string.
    Thanks for your help, unfortunately that doesn't compile either.

    I now get:

    error: expected `)' before 'name'
    error: 'string' does not have a type
    error: prototype for 'char Person::getSex()' does not match any in class 'Person'
    error: candidate is: char Person::getSex() const

    etc..

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Or are those errors in the cpp file where you forgot to change string to std::string?

    Also, if you take laserlight's advice and make getSex const, then you have to add the const keyword to the function definition in the cpp file:
    Code:
    char Person::getSex() const
    BTW, it's easier to help when you post the full errors with line numbers and the code on and near the line numbers the errors refer to. Luckily these errors are pretty obvious so more experienced programmers can guess at the problem.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by kbro3
    Thanks for your help, unfortunately that doesn't compile either.
    I only gave you my suggested corrections for the header file. If you choose to use all my corrections, then you need to make the necessary changes to the source file, including the change with respect to std::string (or the use of a using declaration or using directive). Furthermore, compare your declaration of the setAge member function with your definition of it in the source file.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Aug 2008
    Posts
    33
    Quote Originally Posted by laserlight View Post
    I only gave you my suggested corrections for the header file. If you choose to use all my corrections, then you need to make the necessary changes to the source file, including the change with respect to std::string (or the use of a using declaration or using directive). Furthermore, compare your declaration of the setAge member function with your definition of it in the source file.
    Ok, yeah I see I forgot to put the right parameters into the setAge() member function.

    Here's a question, instead of qualifying string with std::string everywhere, as you mentioned I can use the using keyword.

    Do I need to do this in both Person.h and Person.cpp ?

    Just trying to understand what exactly the problem is.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by kbro3
    Here's a question, instead of qualifying string with std::string everywhere, as you mentioned I can use the using keyword.

    Do I need to do this in both Person.h and Person.cpp ?
    If you want to use a using declaration or using directive, you should only do it in Person.cpp. If you place it in Person.h, you would be doing so at global scope, which means that all source files that include Person.h would be affected. This may seem like a good idea to you at this point, but when you progress to larger projects, it can become a source of confusion and/or mysterious errors (which might even just turn up at run time, if you are particularly unlucky).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Aug 2008
    Posts
    33
    Okay, i've included a string in my Person.h AND Person.cpp

    (#include <string>)

    I also removed the const and std::string, replaced with a using namespace std

    in BOTH Person.h and Person.cpp

    I now get a peculiar error:

    /usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crt1.o: in function `_start':

    /build/buildd/glibc-2.9/csu/../sysdeps/i386/elf/start.S:115: undefined reference to `main'

    collect2: ld returned 1 exit status.


    ^All I gather from that is that it has something to do with the compiler on my linux box?

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    This error is just because you tried to build into an executable program, but did not provide a global main function.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Aug 2008
    Posts
    33
    Quote Originally Posted by laserlight View Post
    This error is just because you tried to build into an executable program, but did not provide a global main function.
    Ah cheers, so if I create a driver with a main function, and compile that, it will compile everything?

    Or, should I use a different option in the compiler, so that it doesn't build an executable, but still compiles?

    Thanks for putting up with endless newbie questions!

  14. #14
    Registered User
    Join Date
    Aug 2008
    Posts
    33
    Okay, got everything to work,

    Turns out I needed to #include <string> in Person.h and also do using namespace std in Person.h

    I then compiled person.cpp (not to executable, but just compile and assemble without linking)

    Last little question is that when i wrote the driver, mainperson.cpp, I did #include "Person.h"
    in it, and found out that this doesn't compile.

    However, when I changed it to #include "Person.cpp" it did compile, and worked as intended, so the header file only gets reference in the class definition .cpp file, not in the driver, the driver needs to reference the file that references the header, is that right? (basically mainperson.cpp -> Person.cpp -> Person.h

    ^That would be correct? (well, it's the only thing that worked for me)

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    No, not quite right unfortunately.

    You really should never #include a cpp file (there are some advanced cases where you might, but don't worry about those now).

    The solution is to #include "Person.h" in both cpp files that use the Person class. Then, add both cpp files to your makefile or command line. You need to compile both, then link them together.

    BTW, as laserlight suggested earlier, it's not good practice to put the using namespace std in your header file like that. It's not a big deal in small projects, it's just something you should know.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Conflicting Header Files
    By X PaYnE X in forum Windows Programming
    Replies: 17
    Last Post: 01-08-2004, 11:28 AM
  2. #define Header files. End Of File Errors.
    By bartybasher in forum C Programming
    Replies: 8
    Last Post: 07-28-2003, 03:03 PM
  3. Using c++ standards
    By subdene in forum C++ Programming
    Replies: 4
    Last Post: 06-06-2002, 09:15 AM
  4. errors reading header files( i believe)
    By knights32ball in forum C++ Programming
    Replies: 0
    Last Post: 03-19-2002, 04:41 AM
  5. doin' classes in header files?
    By face_master in forum C++ Programming
    Replies: 9
    Last Post: 11-14-2001, 03:56 AM