Thread: Linker Error problem

  1. #1
    C(++)(#)
    Join Date
    Jul 2004
    Posts
    309

    Linker Error problem

    First, here is the code:
    Main.CPP
    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include "PBClass.h"
    
    using namespace std;
    
    PhoneBook::PhoneBook* PB = new PhoneBook::PhoneBook::PhoneBook();
    
    int main(int argc, char *argv[])
    {
        PB->AddPerson();
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    PBClass.h
    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    using std::string;
    
    namespace PhoneBook
    {
        class PhoneBook
        {
            private:
                struct person
                {
                    int number;
                    string f_name;
                    string l_name;
                };
                std::vector<person> PVec;
            public:
                PhoneBook();
                ~PhoneBook();
                void AddPerson(person *pb);
                void AddPerson();
                //void RemovePerson(person *pb);
        };
    }
    PBFunctions.CPP
    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include "PBClass.h"
    
    using namespace std;
    
    namespace PhoneBook
    {
        void PhoneBook::AddPerson(PhoneBook::person *pb)
        {
            PVec.push_back(*pb);
        }
    
        void PhoneBook::AddPerson()
        {
            person *npb;
            cout<<"Please put in the phone number of the person:\n";
            cin>>npb->number;
            cout<<"\nPlease input the first name of the person:\n";
            cin>>npb->f_name;
            cout<<"\nPlease input the last name of the person:\n";
            cin>>npb->l_name;
            cout<<endl;
            PVec.push_back(*npb);
            //cout<<PVec.end();
        }
    }
    Now here is the problem: it won't compile. Everytime I try I get this error:

    [Linker error] undefined reference to `PhoneBook::PhoneBook::PhoneBook()'
    and to be perfectly honest, I'm lost as to what to do.
    As always, any help would be appreciated.
    To code is divine

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    You must include code for all the functions you declare in the class interface:

    PBFunctions.CPP
    Code:
    namespace PhoneBook
    {
        PhoneBook::PhoneBook()
        {
        }
    
        PhoneBook::~PhoneBook()
        {
        }
    
        // Plus remainder of your code...
    
    }
    I also think you are missing something in this bit of code:
    Code:
    void PhoneBook::AddPerson()
    {
        person *npb;
        cout<<"Please put in the phone number of the person:\n";
        cin>>npb->number;
        cout<<"\nPlease input the first name of the person:\n";
        cin>>npb->f_name;
        cout<<"\nPlease input the last name of the person:\n";
        cin>>npb->l_name;
        cout<<endl;
        PVec.push_back(*npb);
        //cout<<PVec.end();
    }
    You need to allocate memory to your npb pointer before you start using it. And then you would of course delete the memory allocated to the pointer after you were done using it.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    C(++)(#)
    Join Date
    Jul 2004
    Posts
    309
    Thanks for the help!
    Er...any idea why it won't let me use cout<< on the vector?
    I tried:
    Code:
    cout<<PVec.begin();
    and
    Code:
    cout<<PVec.end()-1;
    but I keep getting an error about there not being a match for it. This is in the function PhoneBook::AddPerson(); by the way.
    To code is divine

  4. #4
    *this
    Join Date
    Mar 2005
    Posts
    498
    Because you have spots in your vector that contain NULL pointers because no memory has been allocated to your person pointer.

    Code:
    person *npb;
    should be:
    Code:
    person *npb = new person;
    Make sure that when you declare a pointer, that before you use the pointer and store variables in its location that you need to assign the memory using the new operator.
    Last edited by JoshR; 06-06-2005 at 08:06 AM.

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    PVec.begin() is an iterator (basically a pointer) to type person. If you had overloaded the stream insertion operator (<<) for type person and you changed the way you were outputting from:

    Code:
    cout << PVec.begin();
    to:

    Code:
    cout << *PVec.begin();
    then it should work.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    *this
    Join Date
    Mar 2005
    Posts
    498
    Quote Originally Posted by hk_mp5kpdw
    then it should work.
    It would just output a 0 because he hasnt assigned memory to the location, so theres no way his variables made it to the location of the pointer.

  7. #7
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by JoshR
    It would just output a 0 because he hasnt assigned memory to the location, so theres no way his variables made it to the location of the pointer.
    I already made mention of the fact the OP was not allocating memory to the npb pointer in my first post. I am assuming he corrected that and has now moved on to another seperate issue.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  8. #8
    *this
    Join Date
    Mar 2005
    Posts
    498
    O_o i should really start reading the full posts before mine

  9. #9
    C(++)(#)
    Join Date
    Jul 2004
    Posts
    309
    Thanks guys, I got it to work.
    However, I was wondering why, with this code:
    Code:
                friend std::ostream& operator<<(std::ostream &o, const person &X)
                {
                    o<<X.number<<" "<<X.f_name<<" "<<X.l_name<<"\n";
                    return o;
                }
    I had to go cout<<*npb, instead of cout<<npb?
    To code is divine

  10. #10
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by 7smurfs
    Thanks guys, I got it to work.
    However, I was wondering why, with this code:
    Code:
    friend std::ostream& operator<<(std::ostream &o, const person &X)
    {
        o<<X.number<<" "<<X.f_name<<" "<<X.l_name<<"\n";
        return o;
    }
    I had to go cout<<*npb, instead of cout<<npb?
    You've defined the stream insertion operator for an object of type person and not for an object of type pointer-to-person. When you output you must therefore output an object of type person and not a pointer to type person. Putting the * in front of your pointer dereferences the pointer turning it from a pointer to type person and into an object of type person.

    You could also have overloaded the stream insertion operator for an object of type pointer-to-person.

    Code:
    friend std::ostream& operator<<(std::ostream &o, const person * X)
    {
        o<<X->number<<" "<<X->f_name<<" "<<X->l_name<<"\n";
        return o;
    }
    The above would allow you to do:
    Code:
    person * npb;
    ...
    cout << npb;
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linker problem... no idea
    By cyreon in forum C Programming
    Replies: 2
    Last Post: 04-03-2009, 02:53 PM
  2. linker
    By George2 in forum C++ Programming
    Replies: 6
    Last Post: 02-23-2008, 01:25 AM
  3. Linker errors in VC++ 2005
    By C+/- in forum C++ Programming
    Replies: 0
    Last Post: 05-18-2007, 07:42 AM
  4. Linker errors when compiling
    By The Wazaa in forum C++ Programming
    Replies: 4
    Last Post: 10-07-2006, 12:55 PM
  5. MSVis-Studio C++ libraries and linker errors
    By kellydj in forum Windows Programming
    Replies: 10
    Last Post: 03-12-2002, 02:03 PM