关于struct:SFML C联合构造函数被隐式删除,因为默认定义会形成错误

SFML C++ union constructor is implicitly deleted because the default definition would be ill formed

我一直在尝试解决这个问题3个小时,但我不能。我正在尝试学习c,但是我被困在这里。我不知道这个问题。我试图创建一个对象池以与我的项目符号对象一起使用,这样我就可以轻松地生成和派生它们而不会发生内存泄漏。我的来源如下:

main.cpp

-第一个错误是Bullet类的构造函数和BulletPool类的更新方法。

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#include <SFML/Graphics.hpp>
#include <stdio.h>
#include <time.h>
#include

#include"bullets.hpp"
#include"enemies.hpp"

BulletPool::BulletPool() { //no matching function for call to 'Bullet::Bullet()'
  // The first one is available.
  firstAvailable_ = &bullets_[0];

  // Each particle points to the next.
  for (int i = 0; i < POOL_SIZE - 1; i++)
  {
    bullets_[i].setNext(&bullets_[i + 1]);
  }

  // The last one terminates the list.
  bullets_[POOL_SIZE - 1].setNext(NULL);
}


Bullet::Bullet(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel) { //  candidate expects 6 arguments, 0 provided
    onScreen_=true;
    inUse = true;
    state_.live.enemy_ = enemy;
    state_.live.velocity_ = vel;
    shape.setRadius(bullet_radius);
    shape.setOrigin(bullet_radius, bullet_radius);
    shape.setFillColor(color);
    shape.setPosition(pos);
}

void Bullet::update(sf::Vector2f screen) {
    shape.move(state_.live.velocity_);
    if((shape.getGlobalBounds().top <  0 || shape.getGlobalBounds().top > 200/*screen.y*/ )&& !state_.live.enemy_) {
        onScreen_ = false;
    }

    if(!onScreen_) {
        inUse = false;
    }
}
void BulletPool::create(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel) {

    assert(firstAvailable_ != NULL);

    Bullet* newBullet = firstAvailable_;
    firstAvailable_ = newBullet->getNext();
    newBullet = new Bullet(pos,color,bullet_radius,enemy,vel);

    // Find an available particle.
    /*for (int i = 0; i < POOL_SIZE; i++) {

        if (!bullets_[i].inUse()) {

            bullets_[i].init(pos,color,bullet_radius,enemy,vel);
            return;
        }
    }*/

}

void BulletPool::update(sf::RenderWindow window) { //initializing argument 1 of 'void BulletPool::update(sf::RenderWindow)'
    for (int i = 0; i < POOL_SIZE; i++) {
        if (!bullets_[i].inUse) {
          // Add this particle to the front of the list.
          bullets_[i].setNext(firstAvailable_);
          firstAvailable_ = &bullets_[i];
        } else {
            window.draw(bullets_[i].shape);
        }
    }
}
Enemy::~Enemy() {};
RedShip::RedShip(sf::Vector2f pos,float side_ln) {
    movement = 10;
    shape.setPointCount(6);
    shape.setPoint(0, sf::Vector2f(side_ln/2, 0));
    shape.setPoint(1, sf::Vector2f(side_ln*3/8,side_ln*3/8));
    shape.setPoint(2, sf::Vector2f(0,side_ln*1/8));
    shape.setPoint(3, sf::Vector2f(side_ln/2,side_ln));
    shape.setPoint(4, sf::Vector2f(side_ln,side_ln*1/8));
    shape.setPoint(5, sf::Vector2f(side_ln*5/8,side_ln*3/8));
    shape.setFillColor(sf::Color::Transparent);
    shape.setOutlineColor(sf::Color::Red);
    shape.setOutlineThickness(5);
    shape.setOrigin(side_ln/2, sqrt((3*side_ln*side_ln)/4));
    shape.setPosition(pos);
}

void RedShip::update(float base_time, BulletPool bullets) {
    if(movement > 1) {
        shape.move(3,1.5);
        movement--;
    }
    else if(movement < -1) {
        shape.move(-3,1.5);
        movement++;
    }
    else if(movement == -1)
        movement = 30;
    else
        movement = -30;

    if(fmod(base_time,20)==0) {
    bullets.create({shape.getPosition().x, shape.getPosition().y + shape.getLocalBounds().height/2}, sf::Color::Red, 4,true, {0,6});
    }
}


GreenShip::GreenShip(sf::Vector2f pos, float side_ln) {
    movement={};
    shape.setPointCount(8);
    shape.setPoint(0, sf::Vector2f(0, 0));
    shape.setPoint(1, sf::Vector2f(0,side_ln*2/3));
    shape.setPoint(2, sf::Vector2f(side_ln/2,side_ln));
    shape.setPoint(3, sf::Vector2f(side_ln,side_ln*2/3));
    shape.setPoint(4, sf::Vector2f(side_ln,0));
    shape.setPoint(5, sf::Vector2f(side_ln*3/4,side_ln/2));
    shape.setPoint(6, sf::Vector2f(side_ln/2,side_ln*3/8));
    shape.setPoint(7, sf::Vector2f(side_ln*1/4,side_ln/2));
    shape.setFillColor(sf::Color::Transparent);
    shape.setOutlineColor(sf::Color::Green);
    shape.setOutlineThickness(5);
    shape.setOrigin(side_ln/2, sqrt((3*side_ln*side_ln)/4));
    shape.setPosition(pos);
}

void GreenShip::update(float base_time,BulletPool bullets) {

    shape.move(0,1);

    if(fmod(base_time,60)==0) {
    //bullets.push_back(new Bullet({shape.getPosition().x, shape.getPosition().y + shape.getLocalBounds().height/2 + 4}, sf::Color::Green, 4,true, 2));
    }
}

class Core {
public:
    const float core_velocity{5};
    int bullet_count{0};

    sf::ConvexShape shape;
    sf::Vector2f velocity;

    Core(float sX, float sY, float scale) {
        shape.setPointCount(12);
        shape.setPoint(0,{scale/2,0});
        shape.setPoint(1,{scale*7/16,scale*2/16});
        shape.setPoint(2,{scale*6/16,scale*4/16});
        shape.setPoint(3,{scale*5/16,scale*7/16+scale/3});
        shape.setPoint(4,{0,scale*10/16+scale/2});
        shape.setPoint(5,{0,scale*13/16+scale/3});
        shape.setPoint(6,{scale*8/16,scale*10/16+scale/3});
        shape.setPoint(7,{scale,scale*13/16+scale/3});
        shape.setPoint(8,{scale,scale*10/16+scale/2});
        shape.setPoint(9,{scale*11/16,scale*7/16+scale/3});
        shape.setPoint(10,{scale*10/16,scale*4/16});
        shape.setPoint(11,{scale*9/16,scale*2/16});
        shape.setFillColor(sf::Color::Transparent);
        shape.setOutlineColor(sf::Color::White);
        shape.setOutlineThickness(7);
        shape.setOrigin(scale/2, scale/2);
        shape.setPosition(sX, sY);
    }

    void update() {

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
            velocity.x = -core_velocity;
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
            velocity.x = core_velocity;
        else
            velocity.x = 0;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
            velocity.y = -core_velocity;
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
            velocity.y = core_velocity;
        else
            velocity.y = 0;

        shape.move(velocity);

    }

    void fire(BulletPool bullets) {
        if(bullet_count < 3) {
            bullets.create({shape.getPosition().x, shape.getPosition().y-shape.getLocalBounds().height/2 -1}, sf::Color::White, 6,false,{0,-8});
            bullet_count++;
        }
    }
};


int main(int argc, char *argv[]) {

    const sf::Vector2f res{480,640};
    printf("Religion ist das Opium des Volkes.\
               -Marx\
"
);
    sf::RenderWindow window(sf::VideoMode(res.x,res.y),"Brick Breaker", sf::Style::None);

    float base_time{0};
    Core core(res.x / 2, res.y /2 + 200, 64);
    GreenShip ship({res.x/2,50},50);
    GreenShip ship1({res.x/2+100,50},50);
    BulletPool bullets;
    //std::vector<Enemy*> enemies;


    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            switch (event.type)
                {

                    case sf::Event::Closed:
                        window.close();
                        break;

                    case sf::Event::KeyPressed:
                        switch (event.key.code) {

                            case sf::Keyboard::Q:
                                core.fire(bullets);
                                break;

                            case sf::Keyboard::Escape:
                                window.close();
                                break;

                            default:
                                break;
                        }
                        break;

                    default:
                        break;
        }
        }

        if(base_time<3600)
            base_time++;
        else
            base_time=0;

        window.clear();
        window.setFramerateLimit(60);

        core.update();
        window.draw(core.shape);

        ship.update(base_time,bullets);
        window.draw(ship.shape);

        ship1.update(base_time,bullets);
        window.draw(ship1.shape);

        bullets.update(window); //use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'

        /*for(auto& b : bullets) {
            if(!b->onScreen) {
                core.bullet_count--;
            }
            else {
                window.draw(b->shape);
                b->update(res,base_time,bullets);
            }
        }*/

        window.display();
    }

    return 0;
}

enemies.hpp(此错误无误)

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
#ifndef ENEMIES_HPP
#define ENEMIES_HPP

class Enemy{
public:
    sf::ConvexShape shape;
    int movement;
    virtual void update(float base_time, BulletPool bullets) = 0;
    virtual ~Enemy() = 0;
};



class RedShip: public Enemy{
public:
    RedShip(sf::Vector2f pos, float side_ln);
    void update(float base_time, BulletPool bullets);
};

class GreenShip: public Enemy{
public:
    GreenShip(sf::Vector2f pos, float side_ln);
    void update(float base_time, BulletPool bullets);
};



#endif

bullets.hpp

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
#ifndef BULLETS_HPP
#define BULLETS_HPP

class Bullet{ //Bullet::Bullet(Bullet&&)// CANT UNDERSTAND WHY THIS POPS UP
public:
    sf::CircleShape shape;
    Bullet(); //unless i add this constructor it gives the error below↓
    Bullet* getNext() const { return state_.next_; }
    void setNext(Bullet* next) { state_.next_ = next; }
    Bullet(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel); //Bullet::Bullet(sf::Vector2f, sf::Color, float, bool, float, float)
    void update(sf::Vector2f screen);
    bool inUse;

private:
    bool onScreen_=true;
    union { //'Bullet::::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
        struct {
        bool enemy_;
        sf::Vector2f velocity_;
        } live; //union member 'Bullet::::live' with non-trivial 'Bullet::::::<constructor>()'

        Bullet *next_;

    } state_;
};

class BulletPool{
public:
    BulletPool();
    void create(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel);
    void update(sf::RenderWindow window);

private:
  static const int POOL_SIZE = 100;
  Bullet bullets_[POOL_SIZE];
  Bullet* firstAvailable_;
};

#endif

所有在eclipse中显示的错误:

1
2
3
4
5
6
7
8
9
[solved]use of deleted function 'Bullet::::<constructor>()'

initializing argument 1 of 'void BulletPool::update(sf::RenderWindow)'

use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'

'Bullet::::<constructor>()' is implicitly deleted because the default definition would be ill-formed:

union member 'Bullet::::live' with non-trivial 'Bullet::::::<constructor>()'

编译器日志(mingw g):

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
10:22:57 **** Incremental Build of configuration Debug for project Black Lambda ****
Info: Configuration"Debug" uses tool-chain"MinGW GCC" that is unsupported on this system, attempting to build anyway.
Info: Internal Builder is used for build
g++ -std=c++0x -DSFML_STATIC -D__GX_EXPERIMENTAL_CXX_0X__ -D_cplusplus=201103L"-IC:\\\\SFML-2.3.2\\\\include" -O0 -g3 -Wall -c -fmessage-length=0 -o main.o"..\\\\main.cpp"
..\\main.cpp: In constructor 'Bullet::Bullet(sf::Vector2f, sf::Color, float, bool, sf::Vector2f)':
..\\main.cpp:24:100: error: use of deleted function 'Bullet::::<constructor>()'
 Bullet::Bullet(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel) {
                                                                                                    ^
In file included from ..\\main.cpp:6:0:
..\\bullets.hpp:16:8: note: 'Bullet::::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
  union {
        ^
..\\bullets.hpp:20:5: error: union member 'Bullet::::live' with non-trivial 'Bullet::::::<constructor>()'
   } live;
     ^
..\\main.cpp: In function 'int main(int, char**)':
..\\main.cpp:261:30: error: use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'
         bullets.update(window);
                              ^
In file included from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:47:0,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/Graphics/RenderWindow.hpp:44:25: note: 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)' is implicitly deleted because the default definition would be ill-formed:
 class SFML_GRAPHICS_API RenderWindow : public Window, public RenderTarget
                         ^
C:\\SFML-2.3.2\\include/SFML/Graphics/RenderWindow.hpp:44:25: error: use of deleted function 'sf::Window::Window(const sf::Window&)'
In file included from C:\\SFML-2.3.2\\include/SFML/Window.hpp:42:0,
                 from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:32,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/Window/Window.hpp:57:23: note: 'sf::Window::Window(const sf::Window&)' is implicitly deleted because the default definition would be ill-formed:
 class SFML_WINDOW_API Window : GlResource, NonCopyable
                       ^
In file included from C:\\SFML-2.3.2\\include/SFML/System/FileInputStream.hpp:34:0,
                 from C:\\SFML-2.3.2\\include/SFML/System.hpp:35,
                 from C:\\SFML-2.3.2\\include/SFML/Window.hpp:32,
                 from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:32,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/System/NonCopyable.hpp:67:5: error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private
     NonCopyable(const NonCopyable&);
     ^
In file included from C:\\SFML-2.3.2\\include/SFML/Window.hpp:42:0,
                 from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:32,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/Window/Window.hpp:57:23: error: within this context
 class SFML_WINDOW_API Window : GlResource, NonCopyable
                       ^
In file included from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:47:0,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/Graphics/RenderWindow.hpp:44:25: error: use of deleted function 'sf::RenderTarget::RenderTarget(const sf::RenderTarget&)'
 class SFML_GRAPHICS_API RenderWindow : public Window, public RenderTarget
                         ^
In file included from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:45:0,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/Graphics/RenderTarget.hpp:51:25: note: 'sf::RenderTarget::RenderTarget(const sf::RenderTarget&)' is implicitly deleted because the default definition would be ill-formed:
 class SFML_GRAPHICS_API RenderTarget : NonCopyable
                         ^
In file included from C:\\SFML-2.3.2\\include/SFML/System/FileInputStream.hpp:34:0,
                 from C:\\SFML-2.3.2\\include/SFML/System.hpp:35,
                 from C:\\SFML-2.3.2\\include/SFML/Window.hpp:32,
                 from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:32,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/System/NonCopyable.hpp:67:5: error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private
     NonCopyable(const NonCopyable&);
     ^
In file included from C:\\SFML-2.3.2\\include/SFML/Graphics.hpp:45:0,
                 from ..\\main.cpp:1:
C:\\SFML-2.3.2\\include/SFML/Graphics/RenderTarget.hpp:51:25: error: within this context
 class SFML_GRAPHICS_API RenderTarget : NonCopyable
                         ^
..\\main.cpp:64:6: error:   initializing argument 1 of 'void BulletPool::update(sf::RenderWindow)'
 void BulletPool::update(sf::RenderWindow window) {
      ^

10:22:59 Build Finished (took 1s.427ms)

我只是想学c
谢谢!谢谢!

编辑
非常感谢您提供的所有帮助。我解决了所有问题。
BulletPool :: update的问题在于,传递了renderwindow对象而没有引用,导致该函数复制窗口,因此无法呈现。


之所以发生此错误,是因为如消息所言,您有一个union成员(您的匿名struct)具有一个成员(velocity_),而该成员没有默认构造函数(或具有非平凡的构造函数, ),从而使整个结构成为非POD(而不是普通的旧数据类型),从而阻止了编译器

简而言之,这里的相关规则是,如果您的union中有某些内容(直接在并集中或包含的结构或类中的某处)中具有非平凡的构造函数(sf::Vector2f在这种情况下),那么您需要为联合编写一个默认的构造函数(以及可能的相关方法,例如,析构函数,复制ctor等)。

如果您考虑一下,这是合理的。如果您的联合中有复杂的事物,那么编译器需要知道该联合的实例在什么状态开始生存。

基本上,解决方案归结为命名联合类型,然后为其编写一个简单(甚至为空)的默认构造函数。尽管您可能要初始化指向nullptrthis+1之类的next_指针。您可能需要编写或至少指定其他基本方法。