Thread: Stubborn classes don't want to be used

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    40

    Stubborn classes don't want to be used

    I am trying to make a function that resizes an array of my person class by recreating it with room for new information, and one that shortens it. Inside these two functions are the problems.

    I am getting wierd compiler errors about my people not having a match. What am I doing wrong?

    The first error is "no match for `person &= person *&'"
    The second is "no match for `person &'"
    The lines for both are marked out below, one inside the add_person function and the other in remove_person.
    Code:
    class room
    {
      public:
      person *occupants;
      unsigned short int num_persons;
      room(void);
      {
        num_persons = 0;
      }
      bool add_person(person *person);
      bool add_person(person *person);
    };
    
    class person
    {
      public:
      //a few completely unrelated variables and functions are here
    }
    
    inline bool room::add_person(person *P = NULL)
    {
      if(!P) return false
      if(num_persons == 0)
      { occupants = new person[1];}
      else
      {
        person *new_list = new person[num_persons + 1];
        for(unsigned short int index = 0; index < num_persons; index += 1)
        {new_list[index] = occupants[index];}
        delete [] occupants;
        occupants = new_list;
      }
      num_persons += 1;
      occupants[num_persons] = P;  //This is line 123; error#1
      return true;
    }
    inline bool room::remove_person(person *P = NULL)
    {
      if(!P) return false
      if(num_persons == 1)
      {delete [] occupants;}
      else
      {
        num_persons -= 1;
        short int skip = 0; //for skipping over the person being removed
        person *new_list = new person[num_persons];
        for(unsigned short int index = 0; index < num_persons; index += 1)
        {
          if(occupants[index] == P) skip = 1;  //This is line 139; error#2
          new_list[index] = occupants[index+skip];
        }
        delete occupants;
        occupants = new_list;
      }
      return true;
    }
    And with the errors, after the first but before the second, there is also something that says "candidates are: class person & person:perator =(const person &)" which points to the ending brace for the person class.

  2. #2
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    In both places, you're using P as if it were a person, but it's really a *person. Dereference P before assigning it or comparing with it.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    I thought you could set a pointer to another pointer, making it point to the same thing, or compare them in the same way, as that is the way the book I learned from did it. I will admit, however, that I only trust this book about as far as I can throw it plus a few inches, but no farther.

    I suppose that's what I get for buying a book where the author uses such statements as "It took two days of research and a lot of thinking to come up with the sample code in Listing 5.1." As if you can teach concepts you just researched, learned and had to think a lot about yourself. I can't complain too much though, as I shouldn't have rushed for the cheapest book without checking them all out thoroughly.

    Anyway, thanks. I'll try to drill the right concept into my skull.

    (edit)
    Actually, I just remembered I did try that with the second error, and I tried again now. The error remains though it now reads "no match for `person & == person &'". Though that did make the first error go away, along with its accompanying extra text.
    Last edited by Loduwijk; 03-21-2006 at 09:00 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I thought you could set a pointer to another pointer, making it point to the same thing, or compare them in the same way, as that is the way the book I learned from did it.
    You can set a pointer to another pointer, but in this case you want to compare with what the pointer points to.
    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
    Apr 2003
    Posts
    2,663
    Stubborn classes don't want to be used
    The Prolitariate rise again!

  6. #6
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    Alright, I've messed around with it a lot more, altering things here and there just to see what would compile completely and what wouldn't. Apparently, it thinks occupants is an array of person rather than *person, and it's not treating it like the pointer it should be, or at least that I thought it should be.

    I figured that out by trying to access the variables of the objects that were supposed to be pointed to, and seeing that it didn't like occupants[index]->variable but didn't mind occupants[index].variable

    It now compiles fully if I change the line with the if statement to the following, telling it to get the address of occupants' memory instead of occupants itself.
    Code:
    if(&occupants[index] == P)
    Although it compiles, it leaves me here wondering whether something is horribly wrong if I have to mangle it like to get it to work. And on the same hand, why wouldn't using *P give the same result as &occupants? And now I'm overthinking it.

    To restate the underlying question, am I doing something wrong here? Do I have an array of pointers or not? Although that compiles in a way that doesn't look right, will it cause problems down the road?

    Apparently at least one thing is still wrong, whatever it is, because the program crashes on me when I try to use it now.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Havent you considered:
    Code:
    if(occupants[index] == *P)
    You could take a look at:
    Code:
    class person
    {
    public:
    	// need this to compare persons for equality (e.g. in room::remove_person() )
    	friend bool operator==(const person& lhs, const person& rhs);
    
    	// ... other functions ...
    };
    
    class room
    {
    public:
    	room() : occupants(0), num_persons(0) {}
    
    	// pass by const reference, you dont need to use pointers here
    	bool add_person(const person& x);
    	bool remove_person(const person& x);
    private:
    	person* occupants;
    	unsigned short int num_persons;
    };
    
    bool room::add_person(const person& x)
    {
    	// create temporary list that is larger than current occupants list
    	person* temp_list = new person[num_persons+1];
    
    	// copy current occupants to temporary list
    	for (unsigned short int index = 0; index < num_persons; ++index)
    	{
    		temp_list[index] = occupants[index];
    	}
    
    	// set occupants to the temporary list
    	delete[] occupants;
    	occupants = temp_list;
    
    	// add new person, then increment num_persons
    	occupants[num_persons++] = x;
    	return true;
    }
    Why cant you use say, a std::vector or similiar container?
    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

  8. #8
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    Quote Originally Posted by laserlight
    Havent you considered:
    Code:
    if(occupants[index] == *P)
    Yes, I thought I mentioned that. Someone farther up in this thread told me to do that, and I did. But then it just changed the compile error. Same type of error, but different extra text after the name of the error.

    You could take a look at:
    (snipped code)
    I'm not fluent in C++ yet, and as such I can't just redo the entire thing in another way without bashing the ol' head on the wall a few times. I'll go through that code snippet and try to see if I can figure out how those changes work and why.

    Why cant you use say, a std::vector or similiar container?
    I've heard several people talk about that in other posts when I've used the search feature to find other related topics. However, I didn't realise it was something I could use here. I'll go look up this vector type and try to learn about it.
    (edit)
    Ah, apparently there is a tutorial in the tutorials section of this very site about the vector class now. So many new things are here since last time I tried to learn C++.
    (/edit)

    Thanks much to all.
    Last edited by Loduwijk; 03-22-2006 at 10:23 AM.

  9. #9
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    (edit)
    I've butchered the code profusely now, and it finally does work, though I'm not sure why I had to do some of the things I did.

    Very bad programming practice, I know, and I won't learn as much from it; but I'll come back after I have a bit more experience and try to look it over again.

    Thanks a ton for all the help.
    (/edit)

    <s> (Bah, everything I do doesn't work. How do you use tags in here for things such as bolt, italics, underline and strikethrough?)
    Alright, I've gone through the vector tutorial, and this does look like it would be much less of a headache.

    Now I only have one slight problem.
    Code:
    vector <person> occupants;
    That doesn't want to work. It gives an error on a line that has nothing at all to do with this whole section of the code, and the error says "instantiated from `vector<person,allocator<person>>::vector(const allocator<person> &)'"

    Then under that it says "instatiated from here" and points to the opening brace for the code block of the room constructor.

    So I assumed I had to tell it this would contain pointers as well. I changed the vector line to
    Code:
    vector <*person> occupants;
    But it tells me "parse error before >" on that line when I do that, so I tried
    Code:
    vector <person> *occupants;
    That compiled successfully on its own, but then when I go to use it, it makes me call push_back like so
    Code:
    occupants->push_back(*P) //instead of occupants.push_back
    And the program crashes because of that line.

    Hopefully this problem will be easier to fix than the larger one I had before.

    And thank you for the continued help. I'll get this stuff sooner or later with all the effort I'm putting into it.
    </s>
    Last edited by Loduwijk; 03-22-2006 at 11:06 AM.

  10. #10
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    So I assumed I had to tell it this would contain pointers as well. I changed the vector line to

    vector <*person> occupants;
    You can treat a vector just like an array. Do you know how arrays work?

    When you declare a vector, you have to specify the type of the things you want to store in the vector. You list the type between the angled brackets. 'occupants' is the name of your vector, just like you have a name for an array that you declare. If you do this:
    Code:
    vector <*person>* occupants;
    You are declaring a variable called 'occupants' that is a pointer to a vector(where the vector contains pointers to person objects). You probably don't want to do that. Keep it simple and declare your vector like this instead:
    Code:
    vector<*person> occupants;
    You can treat that vector just like you would an array that stores pointers to person objects.

    All pointers have to be dereferenced to get the thing they point to:
    Code:
    int num = 10;
    int* ptr = &num;  //ptr equals the 'address of' num
    int total = *ptr;
    If you have an object that is stored in a variable, you call one of the object's member functions like this:
    Code:
    Person bob;
    bob.someMemberFunction();
    Now, if you have a pointer to an object and you want to call one of the object's methods, you first need to dereference the pointer with '*' to get the object, and then you use the dot operator to call the method:
    Code:
    Person bob;
    Person* ptr = &bob;  //ptr equal the 'address-of' bob
    (*ptr).someMemberFunction();
    However, having to type '(*ptr).' is a pain in the neck, so there is a shorthand syntax '->':

    ptr->someMemberFunction();

    The '->' is an instruction to dereference the pointer to give you the object, and then use the dot operator to call the function.

    Code:
    occupants->push_back(*P) //instead of occupants.push_back
    
    
    And the program crashes because of that line.
    That line says to insert *P into the the back of the vector. What is *P? If P is a pointer to a person object, then *P is the person object. But if your vector was declared to store pointers to persons, then you can't insert person objects in the vector.
    Last edited by 7stud; 03-22-2006 at 12:59 PM.

  11. #11
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    Quote Originally Posted by 7stud
    You can treat a vector just like an array. Do you know how arrays work?
    Yes, for the most part.
    When you declare a vector, you have to specify the type of the things you want to store in the vector. (snip)
    Code:
    vector<*person> occupants;
    You can treat that vector just like you would an array that stores pointers to person objects.
    As I said, that is what I did first, and the compiler yelled at me for it. I only tried other variations to see if I could get something to compile.

    The only thing that would compile was
    Code:
    vector<person> occupants;
    And that seems to be working now, oddly.

    Is it possible that my compiler might be at fault for some things? I ask that because I have done some things that others say should work, and not all of it does. Like the previous posts about dereferencing P, and this example right here of making a vector of pointers.

    Either way, as I said in my last post it does at least work now. And I've been going over it again and again, and I think I'm starting to understand some of the things that were confusing me before. However, the compiler still shouts at me from time to time for things that look perfectly fine; for instance, in one function it will yell at me for using a certain variable name and won't calm down until I change it, then in another function it lets me use that name just fine. Maybe background radiation has mutated just the right memory location in my computer to set off a chain reaction which caused it to sprout a tempermental AI...

    or maybe not. Anyway, thanks again for all the help. I'm learning a lot here. My test project I'm making is nearly complete; I can move around between rooms, as can PC-controlled creatures, and there are objects lying about that can be picked up and taken along with you. I tried this last time I was attempting to learn C++, but I didn't get nearly this far.

    One last time, thanks.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Could you post your code with the vector and what problems you are having with it again?

    vector<*person> is incorrect syntax. Based on the code at the top of this thread, vector<person> is the correct equivalent. The error message you mentioned about "instantiated from `vector<person,allocator<person>>::vector(const allocator<person> &)'" was incomplete, it is just more information for the error above it.

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    vector<*person> is incorrect syntax.
    I missed that.

    If you did need a vector of pointers to person objects it would be written like this:

    vector<person*> occupants;

  14. #14
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Either way, as I said in my last post it does at least work now. And I've been going over it again and again, and I think I'm starting to understand some of the things that were confusing me before. However, the compiler still shouts at me from time to time for things that look perfectly fine;
    You should have a test project setup, so you can test short bits of code in there. For instance, you could have tried creating simple vectors, then a vector of pointers, and played around with the vector to see how it works.

    Is it possible that my compiler might be at fault for some things?
    It's not likely. What compiler are you using?

    However, the compiler still shouts at me from time to time for things that look perfectly fine;
    Post examples, and all will be explained away.
    Last edited by 7stud; 03-22-2006 at 02:18 PM.

  15. #15
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    Quote Originally Posted by 7stud
    You should have a test project setup, so you can test short bits of code in there. For instance, you could have tried creating simple vectors, then a vector of pointers, and played around with the vector to see how it works.
    That's what this whole program is, is just a test project to learn how to do these things.
    It's not likely. What compiler are you using?
    Bloodshed's Dev-C++
    Post examples, and all will be explained away.
    I would think the ones I have listed already are baffling enough, especially since they haven't all been explained away.

    I think I mentioned somewhere in the middle of the thread about the garbage errors I get. I really mean garbage, as it might point to line 13927 (the error before it was on line 139), and give an error message of random junk text.

    Then there are things I haven't mentioned, such as the compile screwing up and giving runtime errors. Yes runtime, the compiler itself is giving error windows. And I'm fairly certain it's not just choking on crappy code of mine, since it sometimes happens when I changed something insignificant which can't be at fault (such as adding a simple cout line somewhere), but if I close and restart the compiler and reload my project it compiles fine.

    And then there's that whole P thing where I ended up finding out that "person *occupants" was being treated like an object rather than a pointer to one.

    Anyway, don't bother too much with it. As long as it works for now, and as long as I think I understand why, and can continue to mess around with it and increase my knowledge; then I'm fine. Thanks for all the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multiple Inheritance - Size of Classes?
    By Zeusbwr in forum C++ Programming
    Replies: 10
    Last Post: 11-26-2004, 09:04 AM
  2. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  3. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM