web-dev-qa-db-fra.com

Erreur C2280: Tentative de référence d'une fonction supprimée

Je suis nouveau au développement du jeu et très nouveau pour C++, mais j'ai commencé à développer un petit jeu arkanoïde. Je l'avais couru auparavant, mais après avoir refactoring (introduisant la classe Arkanoidgame), il ne compile pas et je ne peux pas comprendre pourquoi.

L'erreur que je reçois est:

d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\main.cpp(14): error C2280:
    'ArkanoidGame::ArkanoidGame(void)' : attempting to reference a deleted function
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\arkanoidgame.h(25) : 
    compiler has generated 'ArkanoidGame::ArkanoidGame' here

Je ne comprends simplement pas ce que cela signifie et je n'ai aucune idée de quoi faire pour le réparer.

J'ai inclus les classes en question:

Main.cpp:

#include "ArkanoidGame.h"

int main() {
    ArkanoidGame game;
    game.init(800, 600);
    while (game.isRunning()) {
        game.checkInput();
        game.checkCollisions();
        game.draw();
    }
    return 0;
}

Arkanoid.h:

#include "Ball.h"
#include "Pad.h"
#include <SFML/Graphics.hpp>
#include <stdarg.h>
#include <memory>

class ArkanoidGame
{
private:
    bool running;
public:
    void ArkanoidGame::init(int, int);
    bool ArkanoidGame::isRunning();
    void ArkanoidGame::checkCollisions();
    void ArkanoidGame::checkInput();
    void ArkanoidGame::update();
    void ArkanoidGame::draw();
    sf::RenderWindow* window;
    Pad pad;
    Ball ball;
};

Arkanoidgame.cpp:

#include "ArkanoidGame.h"

void ArkanoidGame::init(int windowWidth, int windowHeight) {
    window = new sf::RenderWindow(sf::VideoMode(windowWidth, windowHeight), "Arkanoid!");
    window->setFramerateLimit(60);

    ArkanoidGame::running = true;

    //Init pad
    pad = Pad((float)(windowWidth / 2), (float)(windowHeight - 50));

    //Init ball
    ball = Ball(0.f, 0.f);
}

template<class T1, class T2> bool intersect(T1& mA, T2& mB) {
    return mA.right() >= mB.left() && mA.left() <= mB.right()
        && mA.bottom() >= mB.top() && mA.top() <= mB.bottom();
}

void ArkanoidGame::checkCollisions() {
    if (!intersect(pad, ball)) return;

    ball.velocity.y = -ball.ballVelocity;

    if (ball.x() < pad.x()) {
        ball.velocity.x = -ball.ballVelocity;
    }
    else {
        ball.velocity.x = ball.ballVelocity;
    }
}

void ArkanoidGame::update() {
    //Update positions
    pad.update(window->getSize().x);
    ball.update(window->getSize().x, window->getSize().y);
}

void ArkanoidGame::draw() {
    window->clear(Color::Black);
    window->draw(pad.getShape());
    window->draw(ball.getShape());
    window->display();
}

void ArkanoidGame::checkInput() {
    if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) {
        running = false;
    }
}

bool ArkanoidGame::isRunning() {
    return running;
}
10
Herter

Probablement, soit Pad ou Ball (ou les deux) n'a pas de constructeur par défaut; Par conséquent, on ne peut pas être généré pour une classe qui les contient. Ils doivent être initialisés à l'aide de l'un de leurs constructeurs déclarés.

La meilleure solution consiste à supprimer votre fonction bizarre init et remplacez-la par un constructeur:

ArkanoidGame(int windowWidth, int windowHeight) :
    running(true),
    window(new ...),
    Pad(windowWidth / 2, windowHeight - 50),
    Ball(0,0)
{
    window->setFramerateLimit(60);
}

int main() {
    ArkanoidGame game(800, 600);
    // ...
}

Si vous voulez vraiment une danse d'initialisation en deux étapes pour une raison quelconque, vous devez fournir des constructeurs par défaut pour les deux Pad et Ball. Je ne recommanderais pas que cependant; Il y a moins d'erreurs d'erreur si un objet ne peut pas être créé dans un état non valide.

14
Mike Seymour

Je pense que le problème est que l'une des classes ou la balle de classe n'a pas le constructeur par défaut (vous avez deux membres DTAT de ces classes dans la définition de la classe d'Arkanoidgame: tampon de pad; et ballon à billes;). Dans ce cas, le compilateur a défini le constructeur par défaut de classe arkanoidgame comme supprimé (sinon, il sera mal formé). Cependant dans la première ligne de la principale

ArkanoidGame game;

vous essayez d'appeler le constructeur par défaut de classe arkanoidgame.

Prenez en compte également que les déclarations de fonctions membres doivent avoir des noms non qualifiés dans la définition de la classe. Donc, par exemple, cette déclaration

void ArkanoidGame::init(int, int);

est invalide. Doit être

void init(int, int);
5
Vlad from Moscow

Vous devriez fournir un constructeur pour Arkanoidgame. En arkanoid.h:

ArkanoidGame ();

En arkanoid.cpp:

ArkanoidGame::ArkanoidGame ()
{
    // it is better to initialize members in the constructor,
    // although not strictlynecessary
    running = false;
}
3
Anton Poznyakovskiy