Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error C2280: attempting to reference a deleted function

I'm new to game development and very new to c++, but I've started developing a little Arkanoid game. I've had it running previously, but after refactoring (introducing the ArkanoidGame class) it doesnt compile and I cannot figure out why.

The error I'm getting is:

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

I simply dont understand what this means and have no idea what to do to fix it.

I've included the classes in 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;
}
like image 990
Linora Avatar asked Jan 28 '14 15:01

Linora


3 Answers

You should provide a constructor for ArkanoidGame. In Arkanoid.h:

ArkanoidGame ();

In Arkanoid.cpp:

ArkanoidGame::ArkanoidGame ()
{
    // it is better to initialize members in the constructor,
    // although not strictlynecessary
    running = false;
}
like image 197
Anton Poznyakovskiy Avatar answered Nov 17 '22 05:11

Anton Poznyakovskiy


Presumably, either Pad or Ball (or both) has no default constructor; therefore one can't be generated for a class that contains them. They must be initialised using one of their declared constructors.

The best solution is to remove your weird init function, and replace it with a constructor:

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);
    // ...
}

If you really want a two-stage initialisation dance for some reason, then you'll need to provide default constructors for both Pad and Ball. I wouldn't recommend that though; there's less scope for errors if an object can't be created in an invalid state.

like image 29
Mike Seymour Avatar answered Nov 17 '22 06:11

Mike Seymour


I think that the problem is that either class Pad or class Ball has no the default constructor ( you have two dtat members of these classes in the class definition of ArkanoidGame: Pad pad; and Ball ball;) . In this case the compiler defined the default constructor of class ArkanoidGame as deleted (otherwise it will be ill-formed). However in the first line of main

ArkanoidGame game;

you try to call the default constructor of class ArkanoidGame.

Take also into account that declarations of member functions shall have unqualified names in the class definition. So for example this declaration

void ArkanoidGame::init(int, int);

is invalid. Shall be

void init(int, int);
like image 45
Vlad from Moscow Avatar answered Nov 17 '22 06:11

Vlad from Moscow