C++ 错误 C2280:试图引用已删除的函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21409439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:38:25  来源:igfitidea点击:

error C2280: attempting to reference a deleted function

c++pointerscompiler-errorsdeleted-functions

提问by Herter

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.

我是游戏开发的新手,也是 C++ 的新手,但我已经开始开发一个小打砖块游戏。我以前运行过它,但是在重构(引入 ArkanoidGame 类)之后它没有编译,我不知道为什么。

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:

主.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:

打砖块.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:

打砖块游戏.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;
}

回答by Mike Seymour

Presumably, either Pador 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.

据推测,其中一个PadBall(或两者)没有默认构造函数;因此不能为包含它们的类生成一个。它们必须使用它们声明的构造函数之一进行初始化。

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

最好的解决方案是删除你奇怪的init函数,并用构造函数替换它:

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 Padand Ball. I wouldn't recommend that though; there's less scope for errors if an object can't be created in an invalid state.

如果你真的想出于某种原因两级初始化舞蹈,那么你就需要为双方提供默认的构造函数PadBall。不过我不建议这样做;如果无法在无效状态下创建对象,则错误的范围会更小。

回答by Vlad from Moscow

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

我认为问题在于类 Pad 或类 Ball 都没有默认构造函数(在 ArkanoidGame 的类定义中,您有这些类的两个 dtat 成员:Pad pad; 和 Ball ball;)。在这种情况下,编译器将类 ArkanoidGame 的默认构造函数定义为已删除(否则它将是格式错误的)。但是在 main 的第一行

ArkanoidGame game;

you try to call the default constructor of class ArkanoidGame.

您尝试调用类 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);

回答by Anton Poznyakovskiy

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

您应该为 ArkanoidGame 提供一个构造函数。在打砖块.h中:

ArkanoidGame ();

In Arkanoid.cpp:

在打砖块.cpp中:

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