Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/64: Рейтинг темы: голосов - 64, средняя оценка - 4.61
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420

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

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

Студворк — интернет-сервис помощи студентам
Привет.
У меня есть 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)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.08.2017, 20:43
Ответы с готовыми решениями:

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

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

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

10
Модератор
Эксперт С++
 Аватар для zss
13766 / 10960 / 6490
Регистрация: 18.12.2011
Сообщений: 29,234
02.08.2017, 21:16
Так может у класса Tank не реализована функция
C++
1
Tank& Tank::operator =(const Tank&);
1
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
02.08.2017, 21:44  [ТС]
Мне просто не совсем понятно почему она нужна при удаление из вектора.
И самое главное, почему у класса Снаряда (а он создан идентично танку) при удалении элемента вектора такой проблемы нету...
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
03.08.2017, 00:47
Цитата Сообщение от 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Эксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
03.08.2017, 00:56
Цитата Сообщение от Masai Посмотреть сообщение
Хотя что танки, что снаряды созданы аналогично,
Значит все таки не аналогично. Но телепатов тут нет и что у вас там понаписано в снарядах и танках - неизвестно.

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

P.S. С new действительно написана ярко выраженная белиберда, приводящая лишь к утечке памяти.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
03.08.2017, 01:34
Цитата Сообщение от 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
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
03.08.2017, 09:14  [ТС]
Ого, спасибо. Много дельных замечаний.

Ну что же, приведу 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
03.08.2017, 11:37
Лучший ответ Сообщение было отмечено 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
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
03.08.2017, 11:38  [ТС]
DrOffset, огромное спасибо!!! Это сразу решило все проблемы!
1) Я понял почему неурядица была лишь в классе танка, а не в аналогичном снаряде.
2) Собственно всё заработало!

Сам бы я не докопался бы до такого нюанса... Я что-то совсем забыл просто про те 2 члена...Класс разросся, как-то эта деталь совсем уплыла от меня.
Ну и выше мне верно подсказали не делать динамическими объекты.
0
11 / 11 / 2
Регистрация: 13.07.2014
Сообщений: 420
05.08.2017, 14:48  [ТС]
Господа, а у вас нет идей как сделать в sfml тексту окантовку? Скажем, красный текст и в чёрной окантовочке. Так было бы намного симпатичней.
Вообще признателен форумчанам, благодаря вам я преодолеваю трудности.
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
05.08.2017, 16:04
Цитата Сообщение от Masai Посмотреть сообщение
Господа, а у вас нет идей как сделать в sfml тексту окантовку? Скажем, красный текст и в чёрной окантовочке. Так было бы намного симпатичней.
один вопрос - одна тема.
правила форума прочтите.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.08.2017, 16:04
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru