Thread: Vectors of classes

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Dondrei View Post
    And it works... but I'm wondering why that was necessary. Is it just my compiler being overly fussy? I guess I could just ignore the warning.
    Is it really just fussy?
    What happens if the vector contains more elements than 0x7FFFFFFF (unlikely as that may seem)? Or, dare I say it, that size_t isn't actually unsigned int (there's no such requirements, you know)?
    So no, don't ignore the warning. Do the correct thing.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #17
    Registered User
    Join Date
    Oct 2006
    Posts
    26
    Okay, I think I see the problem, I was thinking int was unsigned but apparently it defaults to signed. That threw me. If I put:

    Code:
    for (unsigned int i=0; i<MonsterList.size(); i++) {}
    It doesn't give me any warnings.

    So is "int" by default signed? Or is that a compiler specific thing?

    Quote Originally Posted by laserlight View Post
    Not quite. Suppose you have a pointer to creature that actually points to a monster object, with creature being a public base class of monster. If you invoke a virtual member function via this pointer, then the actual function that is called is the one from the monster class. If you invoke a non-virtual member function, then the actual function that is called is the one from the creature class, because the pointer is a pointer to creature. If the pointer was a pointer to monster, the member function from the monster class would be called, whether or not the member function is virtual.
    Oh okay, I see.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    int = signed int
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dondrei
    It doesn't give me any warnings.
    That said, note that vector<Monster>::size_type is only required to be an unsigned integer type. It could be unsigned int, or it could be unsigned long, and there may or may not be a difference between unsigned int and unsigned long (though in this case even if there was a difference, it is unlikely to matter).

    Quote Originally Posted by Dondrei
    So is "int" by default signed?
    Yes.
    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. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Dondrei View Post
    So is "int" by default signed?
    It is always signed. The only type that there is a "up to the compiler" option on is char, which is allowed to be either signed or unsigned.

    Also, the CORRECT thing to do is to use vector<monster>::size_type - that is always the correct type. If you recompile the code using unsigned int with a STL implementation that uses a signed type for vector<>::size_type, then you would have to fix the code up again.

    If you are going to use it a lot, you may want to do :
    Code:
    typedef vector<monster>::size_type MonsterSize;
    and then use MonsterSize instead.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    Registered User
    Join Date
    Oct 2006
    Posts
    26
    Huh, so all those variables I've made ints and all the ones I've made signed ints are actually all the same? Now I feel like a dork. :P

    Quote Originally Posted by laserlight View Post
    That said, note that vector<Monster>::size_type is only required to be an unsigned integer type. It could be unsigned int, or it could be unsigned long, and there may or may not be a difference between unsigned int and unsigned long (though in this case even if there was a difference, it is unlikely to matter).
    I see... so why does vector.size() need a specialised type? I would've assumed it would always be an unsigned int. Although I guess that's a good point, it might sometimes need to be long...

    Quote Originally Posted by matsp View Post
    It is always signed. The only type that there is a "up to the compiler" option on is char, which is allowed to be either signed or unsigned.

    Also, the CORRECT thing to do is to use vector<monster>::size_type - that is always the correct type. If you recompile the code using unsigned int with a STL implementation that uses a signed type for vector<>::size_type, then you would have to fix the code up again.

    If you are going to use it a lot, you may want to do :
    Code:
    typedef vector<monster>::size_type MonsterSize;
    and then use MonsterSize instead.

    --
    Mats
    Ah, good suggestion, that would make my code more readable.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Dondrei View Post
    I see... so why does vector.size() need a specialised type? I would've assumed it would always be an unsigned int. Although I guess that's a good point, it might sometimes need to be long...
    Depending on how the implementor wants to do things, size() could be a short, "medium/normak" or long integer, and it may be signed or unsigned. The purpose of defining an own type for a function or set of functions is that it CAN be easily changed with a one-line change. And it may happen that in ONE compiler/processor, using one type is fantastic, but it makes for horrible code / performance in another, because that processor can not do what the first one could, so it requires half a dozen or more instructions to do the same thing that the first processor did in ONE instruction. In this case, it's valid to make some subtle change that makes it all work better.

    But it's mostly a case of "int" and "unsigned int", "unsigned long" or whatever YOU choose, may not be a good representation for number of elements in a vector. Imagine for example that you move to a 64-bit OS and you have a vector of really small items, but you need LOTS of them - more than 4 billion, to be precise. Well, now a 32-bit integer is no good. So your unsigned int is too small... But it's easy for the STL to define vector<X>::size_type as a 64-bit unsigned long - whcih is big enough to hold as much as the memory can cope with and then some.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by matsp
    Depending on how the implementor wants to do things, size() could be a short, "medium/normak" or long integer, and it may be signed or unsigned.
    As I noted in post #19, the type of the integer returned by size() must be an unsigned integer type.
    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. #24
    Registered User
    Join Date
    Oct 2006
    Posts
    26
    Hmm, I have a new problem now, I was trying to switch from using a vector of Monsters to using a vector of pointers to the Monsters like matsp suggested, but it doesn't like it. What I had originally was:

    Code:
    Monster Monster1;
    Monster Monster2;
    
    vector<Monster> MonsterList (30);
    
    int main(int argc, char *argv[])
    {
        MonsterList.push_back(Monster1);
        MonsterList.push_back(Monster2);
    
        MonsterList.at(0).xpos = 500;
    }
    Now, I changed that to:

    Code:
    Monster Monster1;
    Monster Monster2;
    
    vector<Monster*> MonsterList (30);
    
    int main(int argc, char *argv[])
    {
        MonsterList.push_back(&Monster1);
        MonsterList.push_back(&Monster2);
    
        MonsterList.at(0)->xpos = 500;
    }
    It compiles fine, but when it runs it throws an error ("process returned 3", I'm using Codeblocks with mingw). But if I replace the pushbacks like so:

    Code:
    Monster Monster1;
    Monster Monster2;
    
    vector<Monster*> MonsterList (30);
    
    int main(int argc, char *argv[])
    {
        MonsterList[0]=&Monster1;
        MonsterList[1]=&Monster2;
    
        MonsterList.at(0)->xpos = 500;
    }
    That runs fine. So I'm thinking that for some reason the vector's pushback method doesn't like my pointers. Am I doing something wrong?

  10. #25
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    >>vector<Monster*> MonsterList (30);
    This creates 30 empty Monster pointers. When pushing back, you are adding the 31st and 32nd one, and as you try to access the first and second one, you get a problem.
    The second code works because you are assigning to the first and second ones.
    So remove the "(30)" when initializing the vector and use push_back. And for goodness sakes, don't push back the address of a local object (yes, your objects are global now, but I presume you're going to change that sometime later).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #26
    Registered User
    Join Date
    Oct 2006
    Posts
    26
    Aw, crap. I thought that just reserved 30 spaces.

    Hmm. You're right, I was eventually intending on making them local. What should I do when they're local?

  12. #27
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Then you need to allocate them on the heap and preferably use some smart pointers (http://www.boost.org/doc/libs/1_38_0.../smart_ptr.htm).
    Otherwise, the objects will have gone out of scope when you try to access them!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. vector of vectors containing classes
    By larne in forum C++ Programming
    Replies: 3
    Last Post: 01-13-2009, 07:19 AM
  2. classes and vectors
    By izuael in forum C++ Programming
    Replies: 10
    Last Post: 11-27-2006, 04:19 PM
  3. Vectors and custom classes
    By cunnus88 in forum C++ Programming
    Replies: 16
    Last Post: 05-12-2006, 05:11 AM
  4. vectors and classes
    By jimothygu in forum C++ Programming
    Replies: 3
    Last Post: 04-27-2003, 07:53 PM
  5. How To use vectors for custom classes
    By johnnyd in forum C++ Programming
    Replies: 14
    Last Post: 03-25-2003, 10:04 PM