隐式删除SFML C ++联合构造函数,因为默认定义将生成错误

时间:2016-07-13 07:37:26

标签: c++ struct constructor sfml unions

我一直试图解决这个问题3个小时但我不能。我正在努力学习c ++,但我被困在这里。我不知道这个问题。我试图创建一个对象池与我的子弹对象一起使用,这样我就可以轻松地生成和消除它们而不会造成内存泄漏。我的来源如下:

main.cpp

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

#include <SFML/Graphics.hpp>
#include <stdio.h>
#include <time.h>
#include <assert.h>

#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.\n                -Marx\n");
    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(这个没有错误)

#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

#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::<anonymous union>::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
        struct {
        bool enemy_;
        sf::Vector2f velocity_;
        } live; //union member 'Bullet::<anonymous union>::live' with non-trivial 'Bullet::<anonymous union>::<anonymous struct>::<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中:

[solved]use of deleted function 'Bullet::<anonymous union>::<constructor>()'

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

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

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

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

编译器日志(mingw g ++):

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::<anonymous union>::<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::<anonymous union>::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
  union {
        ^
..\bullets.hpp:20:5: error: union member 'Bullet::<anonymous union>::live' with non-trivial 'Bullet::<anonymous union>::<anonymous struct>::<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对象,导致函数复制窗口,因此无法渲染。

1 个答案:

答案 0 :(得分:0)

发生此错误的原因是,正如消息所说,您有一个union成员(您的匿名struct),其成员(velocity_)没有默认构造函数(或者一个非平凡的,)使整个结构成为非POD(不是普通的旧数据类型),这反过来又会阻止编译器

简单地说,这里的相关规则是,如果你的union(直接在联合中或包含的结构或类中的某个地方)有一些具有非平凡构造函数的东西({ {1}}在这种情况下)然后你需要为union 编写默认构造函数(可能还有相关的方法,例如析构函数,复制ctor等)。

如果你考虑一下,这是理性的。如果你的联合中有复杂的东西,那么编译器需要知道该联合的实例在什么状态下开始它们的生命。

基本上,解决方案归结为命名你的联合类型,然后为它编写一个简单的(甚至是空的)默认构造函数。虽然您可能希望将sf::Vector2f指针初始化为next_nullptr或其他内容。您可能需要编写或至少指定其他基本方法。