Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/55: Рейтинг темы: голосов - 55, средняя оценка - 4.65
8 / 8 / 1
Регистрация: 13.07.2014
Сообщений: 365
1

С2280 попытка ссылки на удалённую функцию

02.08.2017, 20:43. Показов 11339. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет.
У меня есть 2 класса. 1 про Танки, другой про снаряды танка.

И там и там есть конструктор по умолчанию и конструктор с нужными аргументами.

В главной функции (в хэдэре) логики я объявляю 2 вектора: один вектор тип танк, другой тип снаряда.

C++
1
2
std::vector <Tank> Army_1;
std::vector <Bomb> Bombs;
в cpp логики я заполняю их.
Что-то типа того:
C++ (Qt)
1
2
3
4
5
for (int i = 0; i < A; i++)
    {
        Tank *tmp_tank = new Tank("Т-34", 1, storage.get_Gren_Housing(), storage.get_Gren_Tower(), tmp, y);
        Army_1.push_back(*tmp_tank);
        }
Бомбы примерно так же:

C++ (Qt)
1
2
Bomb *bomb = new Bomb(Bomb_image, angle_tower, Vector2f(Body_Corpus.getSize().x, Body_Corpus.getSize().y), pos_x, pos_y, Old_Pos, New_Pos);
        Bombs.push_back(*bomb);
А вот сейчас начнутся проблемы.

В функции проверки столкновений я принимаю эти вектора.
C++ (Qt)
1
void Logic::Collision_shell(std::vector <Tank> &Army_1, std::vector <Bomb> &Bomb_all)
Там при столкновении (снаряд попал в танк), снаряд удаляется.
C++ (Qt)
1
    Bomb_all.erase(Bomb_all.begin() + i);
И это работает нормально.

А у танка armor--;

И следом идёт проверка всех танков (отдельным циклом), если броня танка <=0
C++ (Qt)
1
Army_1.erase(Army_1.begin() + i);
И вот тут возникает ошибка при компиляции.

Ошибка C2280 "Tank &Tank::operator =(const Tank &)": предпринята попытка ссылки на удаленную функцию

Хотя что танки, что снаряды созданы аналогично, одинаково переданы в функцию столкновений, у снарядов всё окей, а тут проблема.

П.С Я сейчас не особо думаю об освобождении памяти, прочих вещах, понимаю, что в целом пока это всё не оптимально задумано, но мне бы пока просто протестировать разные аспекты игры. Так что пока мне надо решить проблему в данной реализации.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.08.2017, 20:43
Ответы с готовыми решениями:

Ошибка попытка ссылки на удаленную функцию
Реализую следующую задачу Необходимо реализовать шаблон списка L, который содержит объекты...

Предпринята попытка ссылки на удаленную функцию
friend bool operator&lt;&lt; &lt;&gt;(ofstream &amp;fout, BinarySearchTree&lt;Z&gt; &amp;tree);//ЕСТЬ ДРУЖЕСТВЕННАЯ ФУНКЦИЯ ...

Предпринята попытка ссылки на удаленную функцию
Ошибка C2280 &quot;std::thread &amp;std::thread::operator =(const std::thread &amp;)&quot;: предпринята попытка...

C2280 "bulb &bulb::operator =(const bulb &)": предпринята попытка ссылки на удаленную функцию
Есть некий класс моей реализации под названием bulb, когда я пытаюсь сделать удаление объектов...

10
Модератор
Эксперт С++
13636 / 10857 / 6452
Регистрация: 18.12.2011
Сообщений: 28,939
02.08.2017, 21:16 2
Так может у класса Tank не реализована функция
C++
1
Tank& Tank::operator =(const Tank&);
1
8 / 8 / 1
Регистрация: 13.07.2014
Сообщений: 365
02.08.2017, 21:44  [ТС] 3
Мне просто не совсем понятно почему она нужна при удаление из вектора.
И самое главное, почему у класса Снаряда (а он создан идентично танку) при удалении элемента вектора такой проблемы нету...
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
03.08.2017, 00:47 4
Цитата Сообщение от Masai Посмотреть сообщение
C++
1
2
Bomb *bomb = new Bomb(Bomb_image, angle_tower, Vector2f(Body_Corpus.getSize().x, Body_Corpus.getSize().y), pos_x, pos_y, Old_Pos, New_Pos);
Bombs.push_back(*bomb);
Зачем new? Это утечка памяти.
C++
1
2
3
4
5
6
Bomb bomb(Bomb_image, angle_tower, Vector2f(Body_Corpus.getSize().x, Body_Corpus.getSize().y), pos_x, pos_y, Old_Pos, New_Pos);
Bombs.push_back(bomb);
 
// или вообще так:
 
Bombs.emplace_back(Bomb_image, angle_tower, Vector2f(Body_Corpus.getSize().x, Body_Corpus.getSize().y), pos_x, pos_y, Old_Pos, New_Pos);
0
Вездепух
Эксперт CЭксперт С++
12639 / 6546 / 1758
Регистрация: 18.10.2014
Сообщений: 16,509
03.08.2017, 00:56 5
Цитата Сообщение от Masai Посмотреть сообщение
Хотя что танки, что снаряды созданы аналогично,
Значит все таки не аналогично. Но телепатов тут нет и что у вас там понаписано в снарядах и танках - неизвестно.

Цитата Сообщение от Masai Посмотреть сообщение
Мне просто не совсем понятно почему она нужна при удаление из вектора.
Как это "почему"? При удалении элемента из вектора необходимо передвигать оставшиеся элементы, чтобы закрыть "дырку". Вот тут-то и может понадобиться оператор присваивания.

P.S. С new действительно написана ярко выраженная белиберда, приводящая лишь к утечке памяти.
0
19405 / 10024 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
03.08.2017, 01:34 6
Цитата Сообщение от Masai Посмотреть сообщение
Хотя что танки, что снаряды созданы аналогично, одинаково переданы в функцию столкновений, у снарядов всё окей, а тут проблема.
Надо увидеть объявления обоих классов, где-то в них есть разница, которая так влияет.
Оператор= может быть недоступен по нескольким причинам, например, константы в качестве данных-членов или ссылки могут к этому привести. Смотреть надо объявления твоих классов.
Если, например, у класса есть константы в качестве данных-членов, то компилятор не предоставляет оператор присваивания по умолчанию, т.к. константам нельзя присваивать (по умолчанию выполняется почленное присваивание для всех data members). Если тебе все-таки нужен оператор присваивания в таком классе, его нужно сделать самостоятельно.

Цитата Сообщение от Masai Посмотреть сообщение
в целом пока это всё не оптимально задумано
Оно не "неоптимально", оно просто неверно. Зачем нужно было создавать вообще объект динамически, чтобы потом его по значению положить в вектор?
Все же проще гораздо. И без утечек памяти.
C++
1
2
Bomb bomb(Bomb_image, angle_tower, Vector2f(Body_Corpus.getSize().x, Body_Corpus.getSize().y), pos_x, pos_y, Old_Pos, New_Pos);
Bombs.push_back(bomb);
Цитата Сообщение от Masai Посмотреть сообщение
Мне просто не совсем понятно почему она нужна при удаление из вектора.
Это очень просто: при удалении из середины вектора, чтобы заполнить образовавшееся пространство, элементы "сдвигаются". Сдвиг выполняется через копирование и присваивание элементов. Например, удалили третий, всего шесть. Третьему вызывается деструктор, затем на его месте через конструктор копирования создается новый объект на основе четвертого. Для остального "хвостика" будет выполняться присваивание: пятый присваивается четвертому, шестой - пятому, и общее количество уменьшается на 1.

Описанный порядок лишь упрощенный пример того, как может выполняться актуализация данных в векторе после выполнения удаления из середины. В реальности, скорее всего, будет выполнено три присваивания, а деструктор вызовется у бывшего последнего элемента, после присваивания его предпоследнему (в первом варианте пришлось бы вызывать два деструктора: для удаляемого элемента, и для "лишнего" бывшего последнего). А если у данных вектора доступно перемещение (move-assignment), то будет задействовано оно, а не присваивание. Это не меняет сути, впрочем. Будь то копирование, присваивание или перемещение - они будут вызываться при некоторых операциях с вектором, удалении не с конца, добавлении элементов, операции изменения размера и т.п.
0
8 / 8 / 1
Регистрация: 13.07.2014
Сообщений: 365
03.08.2017, 09:14  [ТС] 7
Ого, спасибо. Много дельных замечаний.

Ну что же, приведу h. классов.

Снаряды:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef  _BOMB
#define  _BOMB
 
 
#include <SFML\Graphics.hpp>
#include <iostream>
using namespace sf;
class Bomb {
public:
    Bomb(Texture *Bomb_image, float angle, Vector2f size, float x, float y, Vector2f Old_Pos, Vector2f New_Pos);
    Bomb();
    ~Bomb();
    Texture Bomb_texture;
    RectangleShape Body_Bomb;
    void    Move();
    Vector2f old_pos;
    Vector2f new_pos;
    Clock clock;
    Time timer;
    float time;
private:
    float speed;
    float x_coord;
    float y_coord;
    float dx;
    float dy;
    float Angle;
};
#endif _BOMB
Танки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifndef _TANK
#define _TANK
#include <SFML\Graphics.hpp>
#include "Bomb.h"
#include <math.h>
 
using namespace sf;
 
class Tank{
public:
    Tank();
    Tank(std::string type, int side, Texture *texture_corpus, Texture *texture_tower, float Corp_x, float Corp_Y);
 
    ~Tank();
    void set_Corpus_Coord_X(int X);
    void set_Corpus_Coord_Y(float Y);
    void set_Angle_Tower(int temp, float time);
    void set_Angle_Corpus(int temp);
    void set_Armor(int X);
    int  get_Coord_Corpus_X ();
    int  get_Coord_Corpus_Y ();
    int  get_Angle();
    bool Reloading;
    bool Tower_rotation_reloading;
    bool Corpus_rotation_reloading;
    float pos_x, pos_y;
    float angle_rotation_speed;
    Clock   Clock_fire;
    Clock   Clock_rotation_tower;
    Clock   Clock_rotation_corpus;
    Time    Reloading_time_fire;
    Time    Reloading_time_angle_tower;
    Time    Reloading_time_angle_corpus;
    long    second;
    long    m_second_tower_rotation;
    long    m_second_corpus_rotation;
    float   armor;
    float   Max_speed;
    RectangleShape Body_Corpus;
    RectangleShape Body_Tower;
    const float mPi = 3.14159265f;
    const float mRad = mPi / 180.f;
    void Update();
    void Fire(Texture *Bomb_image, std::vector <Bomb> &Bombs, bool Enemy, float time);
    void Move(int Y,  float time, bool asd);
    float speed;
    float Coefficient_acceleration;
    Vector2f Corpus_Pos;
private:
    float angle_tower;
    float angle_corpus;
    float size_tank;
    int   Recharge;
};
 
#endif _TANK
Просьба не судить всякие нюансы типа плохой инкапсуляции и т.д. Я пока оформляю так сказать черновик.
Операцию new я уже убрал при создании этих объектов.

А вот про конструктор копирования (или оператор присваивания) я понял логику. Правда пока осталось тайной почему Снаряд на это не жаловался ( Bomb_all.erase(Bomb_all.begin() + i); ), но в целом понял сам смысл. Хотя упоминается это чаще всего в тех случаях когда объекты создаются динамически. Но в моём случае удаления из вектора элемента, это получается всё равно актуально.

Признаться никогда ещё не пользовался констр. копирования и т.д. Не буду наглеть как это проще всего реализовать, погуглю...

Добавлено через 16 секунд
Ого, спасибо. Много дельных замечаний.

Ну что же, приведу h. классов.

Снаряды:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef  _BOMB
#define  _BOMB
 
 
#include <SFML\Graphics.hpp>
#include <iostream>
using namespace sf;
class Bomb {
public:
    Bomb(Texture *Bomb_image, float angle, Vector2f size, float x, float y, Vector2f Old_Pos, Vector2f New_Pos);
    Bomb();
    ~Bomb();
    Texture Bomb_texture;
    RectangleShape Body_Bomb;
    void    Move();
    Vector2f old_pos;
    Vector2f new_pos;
    Clock clock;
    Time timer;
    float time;
private:
    float speed;
    float x_coord;
    float y_coord;
    float dx;
    float dy;
    float Angle;
};
#endif _BOMB
Танки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifndef _TANK
#define _TANK
#include <SFML\Graphics.hpp>
#include "Bomb.h"
#include <math.h>
 
using namespace sf;
 
class Tank{
public:
    Tank();
    Tank(std::string type, int side, Texture *texture_corpus, Texture *texture_tower, float Corp_x, float Corp_Y);
 
    ~Tank();
    void set_Corpus_Coord_X(int X);
    void set_Corpus_Coord_Y(float Y);
    void set_Angle_Tower(int temp, float time);
    void set_Angle_Corpus(int temp);
    void set_Armor(int X);
    int  get_Coord_Corpus_X ();
    int  get_Coord_Corpus_Y ();
    int  get_Angle();
    bool Reloading;
    bool Tower_rotation_reloading;
    bool Corpus_rotation_reloading;
    float pos_x, pos_y;
    float angle_rotation_speed;
    Clock   Clock_fire;
    Clock   Clock_rotation_tower;
    Clock   Clock_rotation_corpus;
    Time    Reloading_time_fire;
    Time    Reloading_time_angle_tower;
    Time    Reloading_time_angle_corpus;
    long    second;
    long    m_second_tower_rotation;
    long    m_second_corpus_rotation;
    float   armor;
    float   Max_speed;
    RectangleShape Body_Corpus;
    RectangleShape Body_Tower;
    const float mPi = 3.14159265f;
    const float mRad = mPi / 180.f;
    void Update();
    void Fire(Texture *Bomb_image, std::vector <Bomb> &Bombs, bool Enemy, float time);
    void Move(int Y,  float time, bool asd);
    float speed;
    float Coefficient_acceleration;
    Vector2f Corpus_Pos;
private:
    float angle_tower;
    float angle_corpus;
    float size_tank;
    int   Recharge;
};
 
#endif _TANK
Просьба не судить всякие нюансы типа плохой инкапсуляции и т.д. Я пока оформляю так сказать черновик.
Операцию new я уже убрал при создании этих объектов.

А вот про конструктор копирования (или оператор присваивания) я понял логику. Правда пока осталось тайной почему Снаряд на это не жаловался ( Bomb_all.erase(Bomb_all.begin() + i); ), но в целом понял сам смысл. Хотя упоминается это чаще всего в тех случаях когда объекты создаются динамически. Но в моём случае удаления из вектора элемента, это получается всё равно актуально.

Признаться никогда ещё не пользовался констр. копирования и т.д. Не буду наглеть как это проще всего реализовать, погуглю...
0
19405 / 10024 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
03.08.2017, 11:37 8
Лучший ответ Сообщение было отмечено Masai как решение

Решение

Цитата Сообщение от Masai Посмотреть сообщение
C++
1
2
const float mPi = 3.14159265f; 
const float mRad = mPi / 180.f;
Как я и говорил, собственно, оператор присваивания помечен как deleted из-за этих двух строк.
Как видно из кода, эти константы не предполагаются к использованию с разной инициализацией от экземпляра к экземпляру, следовательно нет никакого резона оставлять их нестатическими данными-членами. Сделай их статическими, constexpr значениями и проблема исчезнет.
C++
1
2
    static constexpr float mPi = 3.14159265f;
    static constexpr float mRad = mPi / 180.f;
Добавлено через 4 минуты
Цитата Сообщение от Masai Посмотреть сообщение
Правда пока осталось тайной почему Снаряд на это не жаловался
Ну почему тайной-то? Я же написал о возможных причинах в посте #6.
Цитата Сообщение от DrOffset Посмотреть сообщение
Оператор= может быть недоступен по нескольким причинам, например, константы в качестве (нестатических ) данных-членов
Должно же было как-то насторожить?
1
8 / 8 / 1
Регистрация: 13.07.2014
Сообщений: 365
03.08.2017, 11:38  [ТС] 9
DrOffset, огромное спасибо!!! Это сразу решило все проблемы!
1) Я понял почему неурядица была лишь в классе танка, а не в аналогичном снаряде.
2) Собственно всё заработало!

Сам бы я не докопался бы до такого нюанса... Я что-то совсем забыл просто про те 2 члена...Класс разросся, как-то эта деталь совсем уплыла от меня.
Ну и выше мне верно подсказали не делать динамическими объекты.
0
8 / 8 / 1
Регистрация: 13.07.2014
Сообщений: 365
05.08.2017, 14:48  [ТС] 10
Господа, а у вас нет идей как сделать в sfml тексту окантовку? Скажем, красный текст и в чёрной окантовочке. Так было бы намного симпатичней.
Вообще признателен форумчанам, благодаря вам я преодолеваю трудности.
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
05.08.2017, 16:04 11
Цитата Сообщение от Masai Посмотреть сообщение
Господа, а у вас нет идей как сделать в sfml тексту окантовку? Скажем, красный текст и в чёрной окантовочке. Так было бы намного симпатичней.
один вопрос - одна тема.
правила форума прочтите.
0
05.08.2017, 16:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.08.2017, 16:04
Помогаю со студенческими работами здесь

Предпринята попытка ссылки на удаленную функцию
Пытаюсь вставить в код функцию ifstream из библиотеки fstream, выдает ошибку: ...

Ошибка, попытка вызвать функцию
Здравствуйте, использовал разные попытки вызова функции 1 только работает. public void...

Ошибка С2280 при попытке создания потока
При попытке создания потока auto t = new thread(&amp;merge, fin, fout, maxmemory, p) вылезает error...

Попытка вызвать процедуру, как функцию
Привет. Прошу переделать код и скинуть результат. желательно с комментариями. uses crt; var...

Попытка вызвать процедуру как функцию
В 6 строке (if reset(FST)=false then) выдает ошибку &quot;Попытка вызвать процедуру как функцию&quot; ...

Попытка вызвать процедуру как функцию
Пытался прописать процедурой но не выходит. Пишет Компилятор мол попытка вызвать процедуру как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru