我一直试图解决这个问题3个小时但我不能。我正在努力学习c ++,但我被困在这里。我不知道这个问题。我试图创建一个对象池与我的子弹对象一起使用,这样我就可以轻松地生成和消除它们而不会造成内存泄漏。我的来源如下:
main.cpp
- 第一个错误发生在Bullet类的构造函数和BulletPool类的更新方法中。
#include <SFML/Graphics.hpp>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include "bullets.hpp"
#include "enemies.hpp"
BulletPool::BulletPool() { //no matching function for call to 'Bullet::Bullet()'
// The first one is available.
firstAvailable_ = &bullets_[0];
// Each particle points to the next.
for (int i = 0; i < POOL_SIZE - 1; i++)
{
bullets_[i].setNext(&bullets_[i + 1]);
}
// The last one terminates the list.
bullets_[POOL_SIZE - 1].setNext(NULL);
}
Bullet::Bullet(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel) { // candidate expects 6 arguments, 0 provided
onScreen_=true;
inUse = true;
state_.live.enemy_ = enemy;
state_.live.velocity_ = vel;
shape.setRadius(bullet_radius);
shape.setOrigin(bullet_radius, bullet_radius);
shape.setFillColor(color);
shape.setPosition(pos);
}
void Bullet::update(sf::Vector2f screen) {
shape.move(state_.live.velocity_);
if((shape.getGlobalBounds().top < 0 || shape.getGlobalBounds().top > 200/*screen.y*/ )&& !state_.live.enemy_) {
onScreen_ = false;
}
if(!onScreen_) {
inUse = false;
}
}
void BulletPool::create(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel) {
assert(firstAvailable_ != NULL);
Bullet* newBullet = firstAvailable_;
firstAvailable_ = newBullet->getNext();
newBullet = new Bullet(pos,color,bullet_radius,enemy,vel);
// Find an available particle.
/*for (int i = 0; i < POOL_SIZE; i++) {
if (!bullets_[i].inUse()) {
bullets_[i].init(pos,color,bullet_radius,enemy,vel);
return;
}
}*/
}
void BulletPool::update(sf::RenderWindow window) { //initializing argument 1 of 'void BulletPool::update(sf::RenderWindow)'
for (int i = 0; i < POOL_SIZE; i++) {
if (!bullets_[i].inUse) {
// Add this particle to the front of the list.
bullets_[i].setNext(firstAvailable_);
firstAvailable_ = &bullets_[i];
} else {
window.draw(bullets_[i].shape);
}
}
}
Enemy::~Enemy() {};
RedShip::RedShip(sf::Vector2f pos,float side_ln) {
movement = 10;
shape.setPointCount(6);
shape.setPoint(0, sf::Vector2f(side_ln/2, 0));
shape.setPoint(1, sf::Vector2f(side_ln*3/8,side_ln*3/8));
shape.setPoint(2, sf::Vector2f(0,side_ln*1/8));
shape.setPoint(3, sf::Vector2f(side_ln/2,side_ln));
shape.setPoint(4, sf::Vector2f(side_ln,side_ln*1/8));
shape.setPoint(5, sf::Vector2f(side_ln*5/8,side_ln*3/8));
shape.setFillColor(sf::Color::Transparent);
shape.setOutlineColor(sf::Color::Red);
shape.setOutlineThickness(5);
shape.setOrigin(side_ln/2, sqrt((3*side_ln*side_ln)/4));
shape.setPosition(pos);
}
void RedShip::update(float base_time, BulletPool bullets) {
if(movement > 1) {
shape.move(3,1.5);
movement--;
}
else if(movement < -1) {
shape.move(-3,1.5);
movement++;
}
else if(movement == -1)
movement = 30;
else
movement = -30;
if(fmod(base_time,20)==0) {
bullets.create({shape.getPosition().x, shape.getPosition().y + shape.getLocalBounds().height/2}, sf::Color::Red, 4,true, {0,6});
}
}
GreenShip::GreenShip(sf::Vector2f pos, float side_ln) {
movement={};
shape.setPointCount(8);
shape.setPoint(0, sf::Vector2f(0, 0));
shape.setPoint(1, sf::Vector2f(0,side_ln*2/3));
shape.setPoint(2, sf::Vector2f(side_ln/2,side_ln));
shape.setPoint(3, sf::Vector2f(side_ln,side_ln*2/3));
shape.setPoint(4, sf::Vector2f(side_ln,0));
shape.setPoint(5, sf::Vector2f(side_ln*3/4,side_ln/2));
shape.setPoint(6, sf::Vector2f(side_ln/2,side_ln*3/8));
shape.setPoint(7, sf::Vector2f(side_ln*1/4,side_ln/2));
shape.setFillColor(sf::Color::Transparent);
shape.setOutlineColor(sf::Color::Green);
shape.setOutlineThickness(5);
shape.setOrigin(side_ln/2, sqrt((3*side_ln*side_ln)/4));
shape.setPosition(pos);
}
void GreenShip::update(float base_time,BulletPool bullets) {
shape.move(0,1);
if(fmod(base_time,60)==0) {
//bullets.push_back(new Bullet({shape.getPosition().x, shape.getPosition().y + shape.getLocalBounds().height/2 + 4}, sf::Color::Green, 4,true, 2));
}
}
class Core {
public:
const float core_velocity{5};
int bullet_count{0};
sf::ConvexShape shape;
sf::Vector2f velocity;
Core(float sX, float sY, float scale) {
shape.setPointCount(12);
shape.setPoint(0,{scale/2,0});
shape.setPoint(1,{scale*7/16,scale*2/16});
shape.setPoint(2,{scale*6/16,scale*4/16});
shape.setPoint(3,{scale*5/16,scale*7/16+scale/3});
shape.setPoint(4,{0,scale*10/16+scale/2});
shape.setPoint(5,{0,scale*13/16+scale/3});
shape.setPoint(6,{scale*8/16,scale*10/16+scale/3});
shape.setPoint(7,{scale,scale*13/16+scale/3});
shape.setPoint(8,{scale,scale*10/16+scale/2});
shape.setPoint(9,{scale*11/16,scale*7/16+scale/3});
shape.setPoint(10,{scale*10/16,scale*4/16});
shape.setPoint(11,{scale*9/16,scale*2/16});
shape.setFillColor(sf::Color::Transparent);
shape.setOutlineColor(sf::Color::White);
shape.setOutlineThickness(7);
shape.setOrigin(scale/2, scale/2);
shape.setPosition(sX, sY);
}
void update() {
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
velocity.x = -core_velocity;
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
velocity.x = core_velocity;
else
velocity.x = 0;
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
velocity.y = -core_velocity;
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
velocity.y = core_velocity;
else
velocity.y = 0;
shape.move(velocity);
}
void fire(BulletPool bullets) {
if(bullet_count < 3) {
bullets.create({shape.getPosition().x, shape.getPosition().y-shape.getLocalBounds().height/2 -1}, sf::Color::White, 6,false,{0,-8});
bullet_count++;
}
}
};
int main(int argc, char *argv[]) {
const sf::Vector2f res{480,640};
printf("Religion ist das Opium des Volkes.\n -Marx\n");
sf::RenderWindow window(sf::VideoMode(res.x,res.y), "Brick Breaker", sf::Style::None);
float base_time{0};
Core core(res.x / 2, res.y /2 + 200, 64);
GreenShip ship({res.x/2,50},50);
GreenShip ship1({res.x/2+100,50},50);
BulletPool bullets;
//std::vector<Enemy*> enemies;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (event.key.code) {
case sf::Keyboard::Q:
core.fire(bullets);
break;
case sf::Keyboard::Escape:
window.close();
break;
default:
break;
}
break;
default:
break;
}
}
if(base_time<3600)
base_time++;
else
base_time=0;
window.clear();
window.setFramerateLimit(60);
core.update();
window.draw(core.shape);
ship.update(base_time,bullets);
window.draw(ship.shape);
ship1.update(base_time,bullets);
window.draw(ship1.shape);
bullets.update(window); //use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'
/*for(auto& b : bullets) {
if(!b->onScreen) {
core.bullet_count--;
}
else {
window.draw(b->shape);
b->update(res,base_time,bullets);
}
}*/
window.display();
}
return 0;
}
enemies.hpp(这个没有错误)
#ifndef ENEMIES_HPP
#define ENEMIES_HPP
class Enemy{
public:
sf::ConvexShape shape;
int movement;
virtual void update(float base_time, BulletPool bullets) = 0;
virtual ~Enemy() = 0;
};
class RedShip: public Enemy{
public:
RedShip(sf::Vector2f pos, float side_ln);
void update(float base_time, BulletPool bullets);
};
class GreenShip: public Enemy{
public:
GreenShip(sf::Vector2f pos, float side_ln);
void update(float base_time, BulletPool bullets);
};
#endif
bullets.hpp
#ifndef BULLETS_HPP
#define BULLETS_HPP
class Bullet{ //Bullet::Bullet(Bullet&&)// CANT UNDERSTAND WHY THIS POPS UP
public:
sf::CircleShape shape;
Bullet(); //unless i add this constructor it gives the error below↓
Bullet* getNext() const { return state_.next_; }
void setNext(Bullet* next) { state_.next_ = next; }
Bullet(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel); //Bullet::Bullet(sf::Vector2f, sf::Color, float, bool, float, float)
void update(sf::Vector2f screen);
bool inUse;
private:
bool onScreen_=true;
union { //'Bullet::<anonymous union>::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
struct {
bool enemy_;
sf::Vector2f velocity_;
} live; //union member 'Bullet::<anonymous union>::live' with non-trivial 'Bullet::<anonymous union>::<anonymous struct>::<constructor>()'
Bullet *next_;
} state_;
};
class BulletPool{
public:
BulletPool();
void create(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel);
void update(sf::RenderWindow window);
private:
static const int POOL_SIZE = 100;
Bullet bullets_[POOL_SIZE];
Bullet* firstAvailable_;
};
#endif
所有错误都显示在eclipse中:
[solved]use of deleted function 'Bullet::<anonymous union>::<constructor>()'
initializing argument 1 of 'void BulletPool::update(sf::RenderWindow)'
use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'
'Bullet::<anonymous union>::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
union member 'Bullet::<anonymous union>::live' with non-trivial 'Bullet::<anonymous union>::<anonymous struct>::<constructor>()'
编译器日志(mingw g ++):
10:22:57 **** Incremental Build of configuration Debug for project Black Lambda ****
Info: Configuration "Debug" uses tool-chain "MinGW GCC" that is unsupported on this system, attempting to build anyway.
Info: Internal Builder is used for build
g++ -std=c++0x -DSFML_STATIC -D__GX_EXPERIMENTAL_CXX_0X__ -D_cplusplus=201103L "-IC:\\SFML-2.3.2\\include" -O0 -g3 -Wall -c -fmessage-length=0 -o main.o "..\\main.cpp"
..\main.cpp: In constructor 'Bullet::Bullet(sf::Vector2f, sf::Color, float, bool, sf::Vector2f)':
..\main.cpp:24:100: error: use of deleted function 'Bullet::<anonymous union>::<constructor>()'
Bullet::Bullet(sf::Vector2f pos, sf::Color color, float bullet_radius, bool enemy, sf::Vector2f vel) {
^
In file included from ..\main.cpp:6:0:
..\bullets.hpp:16:8: note: 'Bullet::<anonymous union>::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
union {
^
..\bullets.hpp:20:5: error: union member 'Bullet::<anonymous union>::live' with non-trivial 'Bullet::<anonymous union>::<anonymous struct>::<constructor>()'
} live;
^
..\main.cpp: In function 'int main(int, char**)':
..\main.cpp:261:30: error: use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'
bullets.update(window);
^
In file included from C:\SFML-2.3.2\include/SFML/Graphics.hpp:47:0,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/Graphics/RenderWindow.hpp:44:25: note: 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)' is implicitly deleted because the default definition would be ill-formed:
class SFML_GRAPHICS_API RenderWindow : public Window, public RenderTarget
^
C:\SFML-2.3.2\include/SFML/Graphics/RenderWindow.hpp:44:25: error: use of deleted function 'sf::Window::Window(const sf::Window&)'
In file included from C:\SFML-2.3.2\include/SFML/Window.hpp:42:0,
from C:\SFML-2.3.2\include/SFML/Graphics.hpp:32,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/Window/Window.hpp:57:23: note: 'sf::Window::Window(const sf::Window&)' is implicitly deleted because the default definition would be ill-formed:
class SFML_WINDOW_API Window : GlResource, NonCopyable
^
In file included from C:\SFML-2.3.2\include/SFML/System/FileInputStream.hpp:34:0,
from C:\SFML-2.3.2\include/SFML/System.hpp:35,
from C:\SFML-2.3.2\include/SFML/Window.hpp:32,
from C:\SFML-2.3.2\include/SFML/Graphics.hpp:32,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/System/NonCopyable.hpp:67:5: error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private
NonCopyable(const NonCopyable&);
^
In file included from C:\SFML-2.3.2\include/SFML/Window.hpp:42:0,
from C:\SFML-2.3.2\include/SFML/Graphics.hpp:32,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/Window/Window.hpp:57:23: error: within this context
class SFML_WINDOW_API Window : GlResource, NonCopyable
^
In file included from C:\SFML-2.3.2\include/SFML/Graphics.hpp:47:0,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/Graphics/RenderWindow.hpp:44:25: error: use of deleted function 'sf::RenderTarget::RenderTarget(const sf::RenderTarget&)'
class SFML_GRAPHICS_API RenderWindow : public Window, public RenderTarget
^
In file included from C:\SFML-2.3.2\include/SFML/Graphics.hpp:45:0,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/Graphics/RenderTarget.hpp:51:25: note: 'sf::RenderTarget::RenderTarget(const sf::RenderTarget&)' is implicitly deleted because the default definition would be ill-formed:
class SFML_GRAPHICS_API RenderTarget : NonCopyable
^
In file included from C:\SFML-2.3.2\include/SFML/System/FileInputStream.hpp:34:0,
from C:\SFML-2.3.2\include/SFML/System.hpp:35,
from C:\SFML-2.3.2\include/SFML/Window.hpp:32,
from C:\SFML-2.3.2\include/SFML/Graphics.hpp:32,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/System/NonCopyable.hpp:67:5: error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private
NonCopyable(const NonCopyable&);
^
In file included from C:\SFML-2.3.2\include/SFML/Graphics.hpp:45:0,
from ..\main.cpp:1:
C:\SFML-2.3.2\include/SFML/Graphics/RenderTarget.hpp:51:25: error: within this context
class SFML_GRAPHICS_API RenderTarget : NonCopyable
^
..\main.cpp:64:6: error: initializing argument 1 of 'void BulletPool::update(sf::RenderWindow)'
void BulletPool::update(sf::RenderWindow window) {
^
10:22:59 Build Finished (took 1s.427ms)
我只是想学习c ++ 感谢任何帮助或批评,谢谢!
修改 非常感谢所有的帮助。我想出了所有的问题。 BulletPool :: update的问题在于,没有引用传递了renderwindow对象,导致函数复制窗口,因此无法渲染。
答案 0 :(得分:0)
发生此错误的原因是,正如消息所说,您有一个union
成员(您的匿名struct
),其成员(velocity_
)没有默认构造函数(或者一个非平凡的,)使整个结构成为非POD(不是普通的旧数据类型),这反过来又会阻止编译器
简单地说,这里的相关规则是,如果你的union
(直接在联合中或包含的结构或类中的某个地方)有一些具有非平凡构造函数的东西({ {1}}在这种情况下)然后你需要为union 编写默认构造函数(可能还有相关的方法,例如析构函数,复制ctor等)。
如果你考虑一下,这是理性的。如果你的联合中有复杂的东西,那么编译器需要知道该联合的实例在什么状态下开始它们的生命。
基本上,解决方案归结为命名你的联合类型,然后为它编写一个简单的(甚至是空的)默认构造函数。虽然您可能希望将sf::Vector2f
指针初始化为next_
或nullptr
或其他内容。您可能需要编写或至少指定其他基本方法。