Хранение ссылок на указатель

0

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

Tower.cpp

vector<Projectile*> projectiles;

void Tower::fire(Minion& m)
{
    projectiles.push_back(&Projectile(&m, x, 2, y));
}



void Tower::update(Level& level)
{
    for (int i = 0; i < projectiles.size(); i++)
    {
        projectiles.at(i)->update();
    }
}

Projectile.cpp

Minion* m;

void Projectile::update()
{
    float angle = atan((m->getX() - x) / (m->getY() - z));
    x += speed * sin(angle);
    z += speed * cos(angle);
}
  • 1
    Вы не размещаете никаких новых объектов Снаряда.
Теги:

3 ответа

3

Хлоп; святые болтающиеся указатели, бэтмен!

projectiles.push_back(&Projectile(&m, x, 2, y));

Кажется, вы пытаетесь сохранить указатели не только локальными переменными, но и временными объектами! Не уверен, что вы ожидаете от этих указателей после завершения этой строки.

Я не вижу, чтобы вы хранили ссылки где-нибудь, хотя (что хорошо).

Вам в основном придется использовать динамическое размещение здесь, чтобы вы могли управлять временем жизни этих объектов самостоятельно, хотя я бы предложил использовать тип интеллектуального указателя, чтобы вам не пришлось брать на себя слишком большую ответственность :

vector<unique_ptr<Projectile>> projectiles;
// ...
projectiles.emplace_back(new Projectile(&m, x, 2, y));

Пожалуйста, убедитесь, что вы знаете срок службы m. В общем, я рекомендую внимательно посмотреть на все ваши объекты и выяснить:

  • какой кусок кода отвечает за их срок службы, и
  • что такое жизнь

прежде чем вы начнете бросать указатели на все. :)


В частности, избегая необходимости delete.

2

Вы не можете этого сделать:

projectiles.push_back(&Projectile(&m, x, 2, y));

То, что вы на самом деле делаете, - это создать переменную типа Projectile, передав ее адрес в векторный объект, а затем экземпляр Projectile будет уничтожен, поскольку он выходит за рамки. После того, как экземпляр Projectile вышел из сферы действия, указатель ничего не укажет.

Я подозреваю, что вы пытаетесь это сделать:

projectiles.push_back(new Projectile(&m, x, 2, y));

Помните, однако, что вы все еще несете ответственность за уничтожение тех объектов Projectile когда вы закончите с ними.

Например, например, происходит утечка памяти:

projectiles.push_back(new Projectile(&m, x, 2, y));
projectiles.erase(0); // <-- Projectile object still exists, you've only deleted the pointer!!!

Это исправит это:

projectiles.push_back(new Projectile(&m, x, 2, y));

// ... later ...
delete projectiles.at(0);
projectiles.erase(0);

Конечно, идеальным способом сделать это было бы использование умного указателя, такого как unique_ptr или shared_ptr для управления удалением ваших объектов для вас.

Если вы настаиваете на использовании исходных указателей, но используете Boost, вы также можете использовать класс ptr_vector для обработки удаления для вас.

1

Вы храните указатель LOCAL VARIABLES в глобальном std::vector ! Это очень плохо!

Вместо этого я рекомендую использовать контейнер std::shared_ptr. Например:

std::vector<std::shared_ptr<ProjectFile> > projectfiles;

void Tower::fire(Minion &m)
{
    projectfiles.push_back(std::make_shared<ProjectFile>(&m, x, 2, y));
}

Если конструктор ProjectFile не является общедоступным, используйте std::shared_ptr конструктор вместо std::make_shared

projectfiles.push_back(std::shared_ptr<ProjectFile>(new ProjectFile(&m, x, 2, y)));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню