У меня проблемы с созданием объектов и использованием их функций классов с использованием векторов вместо массивов ... Что я делаю не так? - PullRequest
0 голосов
/ 05 января 2012

Я новичок в использовании векторов ... Я только начал изучать их сегодня. Я пытаюсь создать вектор для своего вражеского класса, чтобы я мог динамически создавать их, но я не могу понять, как использовать функции класса ...

Вот класс ...

class Enemy
{
    private:
        SDL_Surface *enemy;
    public:
        Enemy();
       ~Enemy();

        enum Direction { UP, DOWN, LEFT, RIGHT } direction;

        SDL_Rect position;  
        bool alive;

        int setAttributes(int x, int y, int w, int h);
        void update();
        bool checkCollision();
};

Тогда я хочу создать вектор для врагов в игре ...

vector<Enemy> enemy;

Затем я пытаюсь вызвать функции класса следующим образом ...

enemy->setAttributes(0, 50, 32, 32);
enemy->update();

Но когда я компилирую, я получаю следующие ошибки ...

~/code/cpp/sdl$ g++ -o name main.cpp game.cpp player.cpp bullet.cpp enemy.cpp level.cpp -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer
level.cpp: In constructor ‘Level::Level()’:
level.cpp:14: error: base operand of ‘->’ has non-pointer type ‘std::vector<Enemy, std::allocator<Enemy> >’
level.cpp: In member function ‘void Level::update()’:
level.cpp:28: error: base operand of ‘->’ has non-pointer type ‘std::vector<Enemy, std::allocator<Enemy> >’

Что я здесь не так делаю?

Ответы [ 2 ]

1 голос
/ 05 января 2012

Вектор не является указателем (и не действует как единое целое), и, следовательно, не определен operator->.Использование вектора Enemy s аналогично использованию их массива с оператором индекса:

std::vector<Enemy> enemies;
enemies.push_back(Enemy());
enemies[0].update();

Причина, по которой вы можете использовать operator-> для массивов, заключается в том, что массивы преобразуются в указатели и, таким образом,1007 *

Enemy enemies[5];
enemies->update();

эквивалентно

Enemy enemies[5];
(*enemies).update();

, что, в свою очередь, эквивалентно

Enemy enemies[5];
enemies[0].update();

Однако то, что это возможно, не означает, что это хорошая идея: людям будет гораздо меньше проблем с пониманием вашего кода, если вы напишите enemies[0].update() вместо enemies->update().

Если вы хотите пройти через vector<Enemy>, как вы могли бы с указателем на массив, вы должныdo

for (std::vector<Enemy>::iterator it = enemies.begin(); it < enemies.end(); ++it) {
    it->update();
}

Если вы используете C ++ 11 и ленивы, вы можете написать auto вместо std::vector<Enemy>::iterator, и компилятор определит тип для вас.(Вы также можете сохранить значение enemies.end() вне цикла, чтобы не вызывать функцию на каждой итерации, но в любом случае это можно оптимизировать).

0 голосов
/ 05 января 2012
enemy->setAttributes(0, 50, 32, 32);
enemy->update();

должно быть

enemy[0].setAttributes(0, 50, 32, 32);  // Assuming you have at least one object stored in the vector
enemy[0].update();

Обратите внимание, что векторные элементы - это не указатель на объект, а сам объект.

...