Thread: The proper way to do a vector of objects

  1. #1
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68

    The proper way to do a vector of objects

    I've been really busy but managed to get in enough down time to learn somewhat decent info about vectors. Anyways originally my program created a dynamic array of pointers to class objects and I came across a few problems because of this. Apparently an array of pointers is now outta of the question and I will now be switching to a vector of objects instead.

    In case anyone is wondering why I want a list of objects instead of pointers this little comment should clear things up.

    You assumed wrong. tiles[i]->show() dereferences tiles[i] (i.e. accesses whatever it points at) before calling the show() method. That is undefined behaviour. Once undefined behaviour occurs, there is no recovery, and there is nothing the show() method (or any subsequently called function for that matter) can do to recover (short of invoking their own forms of undefined behaviour - compiler specific hacks, etc). Even if the show() method initialises the object correctly, it cannot change the pointer tiles[i] which is in a different scope (within main()).

    What I'm trying to do is create a vector of already intialized objects so that I can use a conditional statement of every single element to properply layer my games art resources. This should also automatically fix a mild unrelated collision dectection problem too but first thing first layering.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You may find this interesting: https://www.youtube.com/watch?v=TC9zhufV_Z8
    I assume you want to use polymorphism, so you'd be using std::vector<std::unique_ptr<ResourceBaseClass>> or std::vector<std::shared_ptr<ResourceBaseClass>>. You create the objects and push them into the vector. I don't know the reference to where you got that reply, so it seems out of place. Need more context to determine what you did wrong.
    Anyway, see the video for more information on how to do game design with C++.
    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.

  3. #3
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Was polymorphism implied or am I blind?

  4. #4
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    I don't think I'm trying to do polymorphism. Aren't dynamic arrays suppose to be similar to vectors? Well I had a problem a while ago with a dynamic array only applying the results of a conditional statement from the last element to the whole array. With a vector wouldn't I be able to apply my condition to each element individually?

    Anyways I needed time to figure out how to print my code to site. I wanted to make sure it was eligible and pasting to notepad and then to the site seems to have did the trick.


    Main function
    Code:
    #include "global.h"
    #include "Function.h"
    #include <iostream>
    #include <vector>
    #include <fstream>
    #include <stdlib.h>
    #include <stdio.h>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "Tile.h"
    #include "Move.h"
    #include "Timer.h"
    #include "constant.h"
    
    
    
    
    
    
    
    
    int main( int argc, char* args[] ) 
    { 
    
    
         //Quit flag 
         bool quit = false; 
     
         //The dot 
         Move character; 
    
    
         //The tiles that will be used 
         Tile *tiles[ TOTAL_TILES ]; 
         
         //The beginning of creating the vector
         std::vector <SideTile> walls; 
    
    
    
    
         //The frame rate regulator 
         Timer delta; 
    
    
         //Initialize SDL 
         if( init() == false ) 
         { 
            return 1; 
         } 
    
    
         //Load the files 
         if( load_files() == false ) 
         { 
            return 1; 
         } 
    
    
         //Clip the tile sheet 
         clip_tiles(); 
         clips_ys();
    
    
         //Set the tiles. Where the vector should be created
         if( set_tiles( tiles, walls) == false ) 
         { 
            return 1; 
         } 
    
    
     //While the user hasn't quit 
     while( quit == false ) 
     { 
        //While there's events to handle 
        while( SDL_PollEvent( &event ) ) 
        { 
            //Handle events for the dot 
            character.attack_input();
            character.handle_input(); 
        
            //If the user has Xed out the window 
            if( event.type == SDL_QUIT ) 
            { 
                //Quit the program 
                quit = true; 
            } 
        } 
    
    
         //Move the dot 
         character.move( tiles,walls, delta.get_ticks() ); 
         character.attack(delta.get_ticks());
     
        //Restart delta timer 
         delta.start(); 
    
    
         //Set the camera 
         character.set_camera(); 
    
    
        
        //Show the tiles
        for( int t = 0; t < TOTAL_TILES; t++ ) 
        { 
            tiles[ t ]->show(); 
        } 
        
    
    
        character.layer_maintance(tiles,walls);
    
    
            
        
        //Update the screen 
        if( SDL_Flip( screen ) == -1 ) 
        { 
            return 1; 
        } 
    
    
            
        
        
     }
      
    
    
     //Clean up 
     clean_up( tiles, walls ); 
    
    
     return 0; 
     }
    Set tiles function where I'm trying to make the vector
    Code:
    bool set_tiles( Tile *tiles[], vector <SideTile>& walls) 
     { 
        //The tile offsets 
        int x = 0, y = 0; 
        int a = 0, b = 0; 
        int p = 0, q = 0; 
        int c = 0, d = 0;
        int z = 0;
    
    
    
    
        //Open the map 
        std::ifstream map( "lazy.map" ); 
        std::ifstream map2( "Zrender.map" ); 
        std::ifstream lv_1acoords ("lv1_aCoords.map"); 
        std::ifstream lv_1zcoords ("lv1_zCoords.map"); 
        std::ifstream lv_1xcoords ("lv1_xCoords.map"); 
        //If the map couldn't be loaded 
        if( map == NULL ) 
        { 
            return false; 
        } 
        if( map2 == NULL ) 
        { 
            return false; 
        } 
         //Initialize the tiles     
         for( int t = 0; t < TOTAL_TILES; t++ ) 
        { 
        //Determines what kind of tile will be made 
            int tileType = -1; 
    
    
        //Read tile from map file 
         map >> tileType; 
    
    
        //If the was a problem in reading the map 
        if( map.fail() == true ) 
        { 
            //Stop loading map 
            map.close(); 
            return false; 
        } 
    
    
        //If the number is a valid tile number 
        if( ( tileType >= 0 ) && ( tileType < TILE_SPRITES ) ) 
        { 
            tiles[ t ] = new Tile(NULL, NULL, NULL , NULL, x, y, tileType ); 
            //Move to next tile spot 
            x += TILE_WIDTH; 
    
    
        } 
    
    
        //If we don't recognize the tile type 
        else 
        { 
            //Stop loading map 
            map.close(); 
            return false; 
        } 
    
    
    
    
    
    
        //If we've gone too far 
        if( x >= LEVEL_WIDTH ) 
        { 
            //Move back 
            x = 0; 
    
    
            //Move to the next row 
            y += TILE_HEIGHT; 
        } 
     } 
     //Ending of for loop
     for( int s = 0; s < TOTAL_TILES_WALL; s++ ) 
     { 
    
    
     //Determines what kind of tile will be made 
     int tileTypeWall = -1; 
     int aPosition = -1, zPosition = -1, xPosition = -1; 
    
    
     //Read tile from map file 
     map2 >> tileTypeWall; 
     lv_1acoords >> aPosition; 
     lv_1zcoords >> zPosition;
     lv_1xcoords >> xPosition;
     //If the was a problem in reading the map 
        if( map2.fail() == true ) 
        { 
            //Stop loading map 
            map2.close(); 
            return false; 
        } 
        
        a = aPosition;
        z = zPosition;
        x = xPosition;
        
        //If the number is a valid tile number 
        if (( tileTypeWall <= TILE_REDCUBE_MEDIUM ) && ( tileTypeWall >= TILE_REDCUBE_LARGE ))
        { 
            SideTile newSideTile( a, b, NULL , NULL, x, z, tileTypeWall );
            walls.push_back(newSideTile);
        } 
    
    
    
    
    
    
    
    
     } 
    
    
     //Close the file 
     map.close(); 
    
    
     //If the map was loaded fine 
     return true; 
     }
    Last edited by LAURENT*; 10-20-2014 at 12:56 PM.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by LAURENT* View Post
    Aren't dynamic arrays suppose to be similar to vectors?
    A vector is a dynamic array encapsulated into a class with additional functions, such as begin, end, resize, size, etc, so yes, that would be an accurate statement.

    Well I had a problem a while ago with a dynamic array only applying the results of a conditional statement from the last element to the whole array. With a vector wouldn't I be able to apply my condition to each element individually?
    I have no idea what this means. Provide or show some example. Arrays and vectors do not differ, so it would stand to reason that you are doing something weird in your code rather than the difference between vectors and arrays.
    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.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    I don't know the reference to where you got that reply, so it seems out of place.
    I wrote the quoted text in another thread, where the context was along the lines of;
    Code:
    //   define a Tile struct/class type with a show() member
    int main()
    {
         Tile *tiles[20];           // uninitialised array of pointer
    
         // intervening code did not initialise the array
    
         for (int i = 0; i < 20; ++i)
            tiles[i]->show();
    }
    and the OP assuming nothing was wrong.

    I have no idea how that extract is relevant to this thread.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,364
    At a quick glance, your use of the vector to hold SideTile objects is correct. What's the problem you're encountering? Are you trying to convert the tiles array to be a vector? If so, that would make sense.

  8. #8
    The Negativity. LAURENT*'s Avatar
    Join Date
    May 2012
    Posts
    68
    Quote Originally Posted by grumpy View Post
    I wrote the quoted text in another thread, where the context was along the lines of;
    Code:
    //   define a Tile struct/class type with a show() member
    int main()
    {
         Tile *tiles[20];           // uninitialised array of pointer
    
         // intervening code did not initialise the array
    
         for (int i = 0; i < 20; ++i)
            tiles[i]->show();
    }
    and the OP assuming nothing was wrong.

    I have no idea how that extract is relevant to this thread.
    The goal was to replace the dynamic array with a vector and to create a vector of class objects. This statement below is the sole cause of me wanting to use a vector with the belief I'll get the functionality I want.
    Code:
    int main()
    {
         Tile *tiles[20];           // uninitialised array of pointer
    
         // intervening code did not initialise the array
    
         for (int i = 0; i < 20; ++i)
            tiles[i]->show();
    }

    This is my previous idea but it did not work. The last element of the array which is 20 is the only one that get's checked. When this happens the the LayerFunction returns 1 for all elements.

    Code:
    int main()
    {
        Tile *tiles[20]; // uninitialised array of pointer
    
    
        // intervening code did not initialise the array
    
    
        for (int i = 0; i < 20; i++)
        if (layerFunction() == 1)
        {    
            //If layerFunction returns 1 show the character first. Behind
            printCharacter();
            printEfects();
            tiles[i]->show();
        }
        
        else if (layerFunction() == 2)
        {
            tiles[i]->show();
            //If layerFunction returns 2 show the last. Front
            printCharacter();
            printEfects();
        }
        
    }

    Quote Originally Posted by Elysia View Post
    A vector is a dynamic array encapsulated into a class with additional functions, such as begin, end, resize, size, etc, so yes, that would be an accurate statement.



    I have no idea what this means. Provide or show some example. Arrays and vectors do not differ, so it would stand to reason that you are doing something weird in your code rather than the difference between vectors and arrays.
    Alright then since this is still on track with the thread. I want to create an array of initialized class objects not an array of pointer.
    UPDATE! As of 10/6/2014

    https://www.dropbox.com/s/2sj6qwpfbb...t%201.zip?dl=0
    Just find the application file and double click it. Controls are (Arrow keys) (Z) (Z + arrow key) (Spacebar)
    Don't play this crappy update. Wait for the newest one which is far more impressive.

    Official Sonic character poll hosted by some guy at Sega..... Sega of America. Vote for blaze because she OP.
    http://blogs.sega.com/2015/08/28/the...down-heats-up/

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,364
    >> I want to create an array of initialized class objects not an array of pointer.

    You're already doing that correctly with std::vector <SideTile> walls. Just follow the same format for your tiles.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by LAURENT* View Post
    The goal was to replace the dynamic array with a vector and to create a vector of class objects. This statement below is the sole cause of me wanting to use a vector with the belief I'll get the functionality I want.

    This is my previous idea but it did not work. The last element of the array which is 20 is the only one that get's checked. When this happens the the LayerFunction returns 1 for all elements.
    Trying to dereference an uninitialized pointer is undefined behavior which means that anything can happen. Since I still don't know what is in LayerFunction, I still don't know why it returns 1 for everything, though.
    But regardless, since you are using uninitialized pointers, it doesn't matter.

    Quote Originally Posted by LAURENT* View Post
    Alright then since this is still on track with the thread. I want to create an array of initialized class objects not an array of pointer.
    Daved points out the right way. Sure remember that you will get no polymorphism if you do that, which is commonly used in game design (just check the link I gave in the first reply!).
    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 objects and Iterator
    By Ivan Novák in forum C++ Programming
    Replies: 3
    Last Post: 01-07-2013, 01:39 PM
  2. Sorting a vector of objects
    By edishuman in forum C++ Programming
    Replies: 5
    Last Post: 02-11-2012, 09:19 AM
  3. Vector of pointers to vector of objects
    By Litz in forum C++ Programming
    Replies: 10
    Last Post: 11-06-2009, 03:29 PM
  4. The proper way to erase a vector element
    By misplaced in forum C++ Programming
    Replies: 10
    Last Post: 03-27-2005, 11:00 AM
  5. maximum objects in vector
    By Shadow12345 in forum C++ Programming
    Replies: 4
    Last Post: 07-21-2002, 12:49 PM