简体   繁体   中英

C++ Iteration over class pointers using std::vector

I am trying to Iterate over a vector using pointers I have a vector called:

 std::vector<GameObject*> objects;

and a load of functions like these:

void Game::update()
 {
    std::vector<GameObject*>::iterator itr;
    for( itr = objects.begin();itr < objects.end();++itr)
    {
        itr->update();//I need to call a abstract function in the GameObject Class
    }
 }
 Game::~Game()
 {

    delete ball;
    delete player;
 }
Game::Game()
{
    ball = new GOBall(800/2 - GOBall::SIZE/2,600/2 - GOBall::SIZE/2);
    player = new GOPlayer(0, 600/2 - GOPlayer::SIZEY/2,ball);
    objects.push_back(ball);
    objects.push_back(player);
}

As you can see I am trying to iterate in a way that still allows me to call the function and also parse the polymorphistic class into other polymorphistic classes(hence the reason its declared before being parsed into the vector), what I keep getting is error:

C2839: invalid return type 'GameObject *const *' for overloaded 'operator ->'

and error:

C2039: 'update' : is not a member of 'std::_Vector_const_iterator<_Ty,_Alloc>'

which tells me i cant call ball->update() or player->update() through the iterator, so how do I do it?

In C++11:

for (GameObject* gameObject : objects) {
    gameObject->update();
}

You need to dereference the iterator

(*itr)->update();

This is the short way to say:

GameObject* pGameObject = *itr;
pGameObject->update();

We can use range-based for loop one step better:

for (auto& game_object : objects)
  game_object->update();

The more complex way is to create your own custom iterator adaptor. Here's an example (complete example will compile and run):

#include <iostream>

#include <vector>
#include <memory>

struct GameObject {
    GameObject(int id)
    : _id { id }
    {}

    virtual void fireLazorz() {
        std::cout << "Game Object " << _id
        << ": I'm a-firin' mah lazorz!" << std::endl;
    }
private:
    int _id;
};


using vec_t = std::vector<std::unique_ptr<GameObject>>;

struct gameobject_deref_iterator : public vec_t::const_iterator
{
    using parent_t = vec_t::const_iterator;

    gameobject_deref_iterator(parent_t src)
    : parent_t(std::move(src))
    {

    }

    // override the indirection operator
    GameObject& operator*() const {
        return *(parent_t::operator*());
    }

    GameObject* operator->() const {
        return parent_t::operator->()->get();
    }

};
using namespace std;

int main()
{
    vec_t gameObjects;

    for(int i = 0 ; i < 10 ; ++i) {
        gameObjects.emplace_back(
                                 new GameObject{ i }
                                 );
    }

    // now iterate the game objects, starting with the 5th one

    gameobject_deref_iterator first { next(begin(gameObjects), 5) };
    gameobject_deref_iterator last { end(gameObjects) };
    cout << "We have " << last - first << " GameObjects:" << endl;
    for(auto it = first ; it != last ; ++it) {
        it->fireLazorz();
    }

    return 0;
}

output:

Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1

Executing the program....
$demo 
We have 5 GameObjects:
Game Object 5: I'm a firin my lazorz!
Game Object 6: I'm a firin my lazorz!
Game Object 7: I'm a firin my lazorz!
Game Object 8: I'm a firin my lazorz!
Game Object 9: I'm a firin my lazorz!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM