c++ - error C2280: intentando hacer referencia a una función eliminada
pointers compiler-errors (3)
Soy nuevo en el desarrollo de juegos y muy nuevo en c ++, pero he comenzado a desarrollar un pequeño juego de Arkanoid. Lo he ejecutado anteriormente, pero después de refactorizar (presentando la clase ArkanoidGame) no se compila y no puedo entender por qué.
El error que estoy obteniendo es:
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
Simplemente no entiendo lo que esto significa y no tengo idea de qué hacer para solucionarlo.
He incluido las clases en cuestión:
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;
}
Creo que el problema es que ni la clase Pad ni la clase Ball tienen el constructor predeterminado (tienes dos miembros dtat de estas clases en la definición de clase de ArkanoidGame: pad pad y Ball ball;). En este caso, el compilador definió el constructor predeterminado de la clase ArkanoidGame como eliminado (de lo contrario, estará mal formado). Sin embargo, en la primera línea de la principal
ArkanoidGame game;
intenta llamar al constructor predeterminado de la clase ArkanoidGame.
Tenga también en cuenta que las declaraciones de las funciones miembro deben tener nombres no calificados en la definición de la clase. Entonces, por ejemplo, esta declaración
void ArkanoidGame::init(int, int);
es inválido. Debería ser
void init(int, int);
Debería proporcionar un constructor para ArkanoidGame. En Arkanoid.h:
ArkanoidGame ();
En Arkanoid.cpp:
ArkanoidGame::ArkanoidGame ()
{
// it is better to initialize members in the constructor,
// although not strictlynecessary
running = false;
}
Presumiblemente, Pad
o Ball
(o ambos) no tienen un constructor predeterminado; por lo tanto, no se puede generar una clase que los contenga. Deben inicializarse utilizando uno de sus constructores declarados.
La mejor solución es eliminar su extraña función init
y reemplazarla con un 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);
// ...
}
Si realmente quieres un baile de inicialización en dos etapas por alguna razón, entonces necesitarás proporcionar constructores por defecto para Pad
y Ball
. Aunque no lo recomendaría; hay menos margen para errores si un objeto no se puede crear en un estado no válido.