C++ 错误 (C2280) 尝试访问已删除的函数
C++ Error (C2280) tring to access a deleted function
所以,我试图用 opengl 和 sfml 制作一个 2d 游戏,
所以我在输入命名空间中创建了一个按钮 class,
我在其中创建了一个 render() 函数,但是当我调用它时(无论我是否使用指针)即使我传递了所有必需的参数它仍然给出
我出错了,说我正在尝试访问已删除的函数
这是按钮 header:
#pragma once
#include <SFML/Graphics.hpp>
#include "InputManager.h"
namespace input {
class Button {
private:
bool m_Selected, m_Clicked;
sf::Vector2f m_Position;
sf::Sprite m_Sprite;
sf::Texture m_Texture;
public:
Button(sf::Vector2f position, sf::Sprite sprite);
Button(sf::Vector2f position, sf::Texture texture);
Button(sf::Vector2f position);
Button();
~Button();
void update(engine::InputManager inputManager);
void render(sf::RenderWindow window);
inline bool isClicked() { return m_Clicked; }
inline bool isSelected() { return m_Selected; }
inline sf::Vector2f getPosition() { return m_Position; }
void setPosition(sf::Vector2f position) { m_Position = position; }
};
}
这里是 Button.cpp:
#include "Button.h"
namespace input {
Button::Button(sf::Vector2f position, sf::Sprite texture) : m_Position(position), m_Sprite(texture) {
m_Sprite.setPosition(m_Position);
}
Button::Button(sf::Vector2f position, sf::Texture texture) : m_Position(position), m_Texture(texture) {
m_Sprite.setTexture(m_Texture);
m_Sprite.setPosition(m_Position);
}
Button::Button(sf::Vector2f position) : m_Position(position) {
m_Sprite.setPosition(m_Position);
}
void Button::update(engine::InputManager inputManager) {}
void Button::render(sf::RenderWindow window) {
window.draw(m_Sprite);
}
Button::~Button() {
delete &m_Position;
delete &m_Texture;
delete &m_Clicked;
delete &m_Selected;
}
}
这里是 main.cpp 代码:
#include <iostream>
#include <vector>
#include "InputManager.h"
#include "Button.h"
#define WIDTH 800
#define HEIGHT 600
#define TITLE "C++ Platformer"
int main() {
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), TITLE, sf::Style::Close | sf::Style::Titlebar);
sf::Texture ButtonTexture;
ButtonTexture.loadFromFile("Texture.png");
sf::Sprite sprite;
sprite.setTexture(ButtonTexture);
input::Button* button = new input::Button(sf::Vector2f(100.f, 100.f), sprite);
int fps = 0;
int ticks = 0;
sf::Clock clock;
sf::Clock FpsClock;
sf::Time time;
sf::Time Fpstime;
long delta = 0;
long target = 1000000 / 60;
engine::InputManager IManager;
sf::Event ev;
while (window.isOpen()) {
while (window.pollEvent(ev)) {
if (ev.type == sf::Event::Closed) window.close();
if (ev.key.code == sf::Keyboard::Escape) window.close();
if (ev.type == sf::Event::KeyPressed) IManager.onKeyDown(ev.key.code);
}
time = clock.getElapsedTime();
if (target > time.asMicroseconds()) {
clock.restart();
// UPDATE
button->update(IManager);
delta = time.asMicroseconds() % 60;
target = 1000000 / 60 + delta;
ticks++;
} Fpstime = FpsClock.getElapsedTime();
if (Fpstime.asSeconds() >= 1) {
std::cout << "FPS: " << fps << " Ticks: " << ticks << std::endl;
FpsClock.restart();
fps = 0;
}
fps++;
// RENDER
button->render(window);
}
return EXIT_SUCCESS;
}
我已经在 Microsoft 文档和其他 Whosebug 问题上进行了搜索,但找不到与我类似的案例,希望有人能提供帮助,谢谢
首先。什么...
Button::~Button() {
delete &m_Position;
delete &m_Texture;
delete &m_Clicked;
delete &m_Selected;
}
你不应该那样做。
但是回到你的错误。它非常具有描述性。您正在尝试使用最有可能被明确删除的功能。像这样:
struct Test {
Test(const Test & other) = delete;
};
显然我现在无法复制 Test
因为我删除了复制构造函数。
这是什么 sf::RenderWindow does by inheriting from sf::NonCopyable class.
并且由于您的 render()
方法通过复制而不是引用来获取它。它显然试图做一些被禁止的事情。
你应该改变这个:
void Button::render(sf::RenderWindow window)
为此:
void Button::render(sf::RenderWindow & window)
问题是 sf::RenderWindow
是不可复制的。这是一件好事,因为这意味着您不会不小心对拥有多个 windows 感到困惑,并且在您创建新的 window 时以及它的归属地都一目了然。但是,在像
这样的函数签名中
void Button::render(sf::RenderWindow window);
您正在接受 sf::RenderWindow
按价值。这意味着无论何时调用 Button::render
并传递 window,window 在被函数接收之前都会被 复制 。看到问题了吗?
您需要通过引用接受呈现 window,以确保您不会尝试创建副本:
void Button::render(sf::RenderWindow& window);
旁白:正如 NathanOliver 所指出的,您尝试 delete
您的 Button
析构函数中的所有实例成员,即使它们不是指针,并且您没有专门分配它们new
。只 delete
你 new
的东西,如果可以的话,完全避免 new
/delete
。
如果您不确定通过引用传递的含义,或者 new
和 delete
的用途,我建议您获取一份 good C++ book .
所以,我试图用 opengl 和 sfml 制作一个 2d 游戏, 所以我在输入命名空间中创建了一个按钮 class, 我在其中创建了一个 render() 函数,但是当我调用它时(无论我是否使用指针)即使我传递了所有必需的参数它仍然给出 我出错了,说我正在尝试访问已删除的函数 这是按钮 header:
#pragma once
#include <SFML/Graphics.hpp>
#include "InputManager.h"
namespace input {
class Button {
private:
bool m_Selected, m_Clicked;
sf::Vector2f m_Position;
sf::Sprite m_Sprite;
sf::Texture m_Texture;
public:
Button(sf::Vector2f position, sf::Sprite sprite);
Button(sf::Vector2f position, sf::Texture texture);
Button(sf::Vector2f position);
Button();
~Button();
void update(engine::InputManager inputManager);
void render(sf::RenderWindow window);
inline bool isClicked() { return m_Clicked; }
inline bool isSelected() { return m_Selected; }
inline sf::Vector2f getPosition() { return m_Position; }
void setPosition(sf::Vector2f position) { m_Position = position; }
};
}
这里是 Button.cpp:
#include "Button.h"
namespace input {
Button::Button(sf::Vector2f position, sf::Sprite texture) : m_Position(position), m_Sprite(texture) {
m_Sprite.setPosition(m_Position);
}
Button::Button(sf::Vector2f position, sf::Texture texture) : m_Position(position), m_Texture(texture) {
m_Sprite.setTexture(m_Texture);
m_Sprite.setPosition(m_Position);
}
Button::Button(sf::Vector2f position) : m_Position(position) {
m_Sprite.setPosition(m_Position);
}
void Button::update(engine::InputManager inputManager) {}
void Button::render(sf::RenderWindow window) {
window.draw(m_Sprite);
}
Button::~Button() {
delete &m_Position;
delete &m_Texture;
delete &m_Clicked;
delete &m_Selected;
}
}
这里是 main.cpp 代码:
#include <iostream>
#include <vector>
#include "InputManager.h"
#include "Button.h"
#define WIDTH 800
#define HEIGHT 600
#define TITLE "C++ Platformer"
int main() {
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), TITLE, sf::Style::Close | sf::Style::Titlebar);
sf::Texture ButtonTexture;
ButtonTexture.loadFromFile("Texture.png");
sf::Sprite sprite;
sprite.setTexture(ButtonTexture);
input::Button* button = new input::Button(sf::Vector2f(100.f, 100.f), sprite);
int fps = 0;
int ticks = 0;
sf::Clock clock;
sf::Clock FpsClock;
sf::Time time;
sf::Time Fpstime;
long delta = 0;
long target = 1000000 / 60;
engine::InputManager IManager;
sf::Event ev;
while (window.isOpen()) {
while (window.pollEvent(ev)) {
if (ev.type == sf::Event::Closed) window.close();
if (ev.key.code == sf::Keyboard::Escape) window.close();
if (ev.type == sf::Event::KeyPressed) IManager.onKeyDown(ev.key.code);
}
time = clock.getElapsedTime();
if (target > time.asMicroseconds()) {
clock.restart();
// UPDATE
button->update(IManager);
delta = time.asMicroseconds() % 60;
target = 1000000 / 60 + delta;
ticks++;
} Fpstime = FpsClock.getElapsedTime();
if (Fpstime.asSeconds() >= 1) {
std::cout << "FPS: " << fps << " Ticks: " << ticks << std::endl;
FpsClock.restart();
fps = 0;
}
fps++;
// RENDER
button->render(window);
}
return EXIT_SUCCESS;
}
我已经在 Microsoft 文档和其他 Whosebug 问题上进行了搜索,但找不到与我类似的案例,希望有人能提供帮助,谢谢
首先。什么...
Button::~Button() {
delete &m_Position;
delete &m_Texture;
delete &m_Clicked;
delete &m_Selected;
}
你不应该那样做。
但是回到你的错误。它非常具有描述性。您正在尝试使用最有可能被明确删除的功能。像这样:
struct Test {
Test(const Test & other) = delete;
};
显然我现在无法复制 Test
因为我删除了复制构造函数。
这是什么 sf::RenderWindow does by inheriting from sf::NonCopyable class.
并且由于您的 render()
方法通过复制而不是引用来获取它。它显然试图做一些被禁止的事情。
你应该改变这个:
void Button::render(sf::RenderWindow window)
为此:
void Button::render(sf::RenderWindow & window)
问题是 sf::RenderWindow
是不可复制的。这是一件好事,因为这意味着您不会不小心对拥有多个 windows 感到困惑,并且在您创建新的 window 时以及它的归属地都一目了然。但是,在像
void Button::render(sf::RenderWindow window);
您正在接受 sf::RenderWindow
按价值。这意味着无论何时调用 Button::render
并传递 window,window 在被函数接收之前都会被 复制 。看到问题了吗?
您需要通过引用接受呈现 window,以确保您不会尝试创建副本:
void Button::render(sf::RenderWindow& window);
旁白:正如 NathanOliver 所指出的,您尝试 delete
您的 Button
析构函数中的所有实例成员,即使它们不是指针,并且您没有专门分配它们new
。只 delete
你 new
的东西,如果可以的话,完全避免 new
/delete
。
如果您不确定通过引用传递的含义,或者 new
和 delete
的用途,我建议您获取一份 good C++ book .