error C2280: attempting to reference a deleted function - c++

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;
}

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.

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);

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;
}

Related

C++, How to call a child method in the parent class

I have two classes in my project:
Style
Line
In which, Line is the child of Style, so Line inherits from Style.
I need that when I call a method of the class Style (the parent) from Line (the child), the method of Style calls a method of the child, for your better understanding here is the code:
Line calls the Style function --> Style calls the Line function
Style.h:
#pragma once
class Style
{
public:
void set_size(int width, int height);
protected:
int width, height;
};
Style.cpp:
#include "Style.h"
void Style::set_size(int width, int height)
{
Style::width = width;
Style::height = height;
}
Line.h:
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : public Style
{
public:
void draw();
vector <vector<char>> matrix;
};
Line.cpp:
#include "Line.h"
void Line::draw()
{
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::height; i++)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
Main.cpp:
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10);
}
Obviously, this code for now does nothing much, it only modifies Style variables.
What I expect is that when I call set_size(), in addition to changing the value of the variables width and height, it will also change the size of the matrix
I don't know how to do what I said before.
I don't even know if it is a good method that Line is a child of Style, in any case other solutions that do not include inheritance are welcome.
Thanks in advance.
You need virtual functions, it would seem that set_size is the one that should be virtual, but this is not the only way to do it.
class Style
{
public:
virtual void set_size(int width, int height);
virtual ~Style() {}
protected:
int width, height;
};
class Line : public Style
{
public:
void draw();
virtual void set_size(int width, int height)
{
Style::set_size(width, height);
... // some code to resize matrix
}
vector <vector<char>> matrix;
};
But I question if this is good design, Style should be an attribute of Line (i.e. a member variable). Inheritance doesn't seem appropriate here, which is why you are struggling to write the code.
I tried to have implementation and declaration in the same file. but you can structure it as you may feel good for your project.
#include <iostream>
#include <vector>
using namespace std;
class Line;
class Style
{
public:
void set_size(int width, int height){
w = width;
h = height;
}
void print(){
cout << w << ", " << h << endl;
}
friend class Line;
protected:
int w, h;
};
class Line : public Style
{
public:
void draw(){
vector <char> row;
int i, j;
for (i = 0; i < w; i++)
{
row.clear();
for (j = 0; j < h; i++)
{
row.push_back('-');
}
matrix.push_back(row);
}
}
vector<vector<char>> matrix;
};
int main()
{
Line line;
line.set_size(10, 10);
line.print();
line.set_size(20, 20);
line.print();
}
We can just overload set_size within Line and call the other set_size from there and also the draw function to recreate the matrix.
This solution provides simple static polymorphism, that means a Line cannot be assigned to a Style - you probably do not need this? So the compiler always statically at compile-time knows, which class an object really is and can call the correct member function. No virtual member functions are needed.
There also were bugs in the draw function, which I corrected below.
The changes to your code are marked with a comment in the following.
// Line.h
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : private Style // use private inheritance for static polymorphism
{
public:
void draw();
void set_size(int width, int height); // overload set_size (override only for virtual functions)
vector <vector<char>> matrix;
};
// Line.cpp
#include "Line.h"
void Line::set_size(int width, int height)
{
Style::set_size(width, height); // call set_size() function of style
draw(); // draw() to set matrix to new size
}
void Line::draw()
{
Line::matrix.clear(); // clear matrix, if draw() is called more than once
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::width; j++) // use Line::width and j++ (there were bugs)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
// Main.cpp
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10); // calls the enhanced Line::set_size
// The following compilation errors (when the comments are removed) are good, as they prevent wrong usage of the current class definitions
// Style style = line; // would give error, as we have private inheritance and want to prevent 'slicing' and the calling of the wrong member functions; if a Line should be able to be assigned to a Style, you need public dynamic inheritance and virtual functions, as provided in other answers. If you do not need to assign a Line to a Style, use the simpler implementation from this answer.
// Style* stylepointer = &line; // also would give an error
}
Optionally draw() and matrix can be made private in Line.
If you need to call functions (other than set_size) of Style directly, you can use public inheritance, but make all constructors (including default/copy/move) of Style protected, so that only children like Line can call them. This would also prevent assignments of Line to Style.
EDIT: I'm completely changing the original answer since the question was modified too. If I get it right, you would like line.set_size(...) to call first the parent method and then to update the matrix. You cannot do that, because only one method will be called, and not both of them what you could do is add a set_size method for Line that calls Style's one.
line.h should be changed like this:
class Line : public Style
{
public:
void draw();
void set_size(int width, int height);
vector<vector<char>> matrix;
};
and you should append this to line.cpp:
void Line::set_size(int width, int height)
{
// call parent method
Style::set_size(width, height);
// now update matrix
int i, j;
matrix.resize(height);
for (auto &row : matrix)
{
row.resize(width);
}
}
Hope it helps!
Base function must be virtual for runtime inheritance.
as follows example
class base {
public:
virtual void print()
{
cout << "print base class\n";
}
void show()
{
cout << "show base class\n";
}
};
class derived : public base {
public:
void print()
{
cout << "print derived class\n";
}
void show()
{
cout << "show derived class\n";
}
};
int main()
{
base *bptr;
derived d;
bptr = &d;
// Virtual function, binded at runtime
bptr->print();
// Non-virtual function, binded at compile time
bptr->show();
return 0;
}

C++ Constructor error when I separate the function prototype from the definition

When I have both the prototype and definition in the same header file (as shown below), and I create an object in main (source.cpp) with Cube c1{}; I get no error and the default constructor works; c1's side will be defaulted to 0.0
class Cube {
private:
double side;
static int counter;
//this is cube.h
public:
Cube(double s = 0.0) :side{ s } { //constructor
counter++;
}
};
However, when I separate the interface from the implementation like this:
class Cube {
private:
double side;
static int counter; //static data
//this is cube.h
public:
Cube(double);
};
Its implementation:
#include <iostream>
#include "Cube.h"
int Cube::counter{ 0 };
//this is cube.cpp
Cube::Cube(double s = 0.0) :side{ s } {
counter++;
}
And I go to the main function in source.cpp, Cube c1{}; now gives me the error:
no instance of constructor "Cube::Cube" matches the argument list
Note: When I gave c1 a value, like Cube c1{5}; it works in both cases.
You should put the default argument to the declaration Cube(double = 0.0);, not the definition. Otherwise the matching function cannot be found in other files.

C++ passing class to constructor = not passing same instance?

It seems that, when I pass an class it is not passing a persistant (the same) instance of that class as I would expect. I'm assuming this has something to do with memory state but I would appreciate it if someone could explain exactly what is happening. The issue is easily demonstrated as follows :
Main.ino
#include "Debug.h"
#include "Box.h"
Debug debug;
Box box(debug);
void loop(){
debug.message("loop");
debug.line();
}
void setup(){
debug.init();
box.init();
debug.message("Setup Complete");
debug.line();
}
Debug.h
#ifndef DEBUG_H
#define DEBUG_H
class Debug {
private:
bool state;
public:
Debug();
void init();
void message(const char *str);
void message(int);
void line();
};
#endif
Debug.cpp
#include "Debug.h"
#include <Arduino.h>
Debug::Debug() : state(false) {}
void Debug::init() {
if (state == false){
Serial.begin(9600);
state = true;
}
}
void Debug::message(const char *messageChar) {
if (state){
const char *p;
p = messageChar;
while (*p) {
Serial.print(*p);
p++;
}
}
}
void Debug::message(int messageInt) {
if (state){
Serial.print(messageInt);
}
}
void Debug::line() {
if (state){
Serial.println();
}
}
Box.h
#ifndef BOX_H
#define BOX_H
#include "Debug.h"
class Box {
private:
Debug debug;
public:
Box(Debug &debug);
void init();
};
#endif
Box.cpp
#include "Box.h"
#include <Arduino.h>
Box::Box(Debug &debug):
debug(debug)
{}
void Box::init(){
// Switches
pinMode(28, INPUT_PULLUP);
debug.message("Box intialized");
debug.line();
}
So the above code outputs to serial:
Setup Complete
If I modify Box::init() to
void Box::init(){
// Switches
pinMode(28, INPUT_PULLUP);
debug.init();
debug.message("Box intialized");
debug.line();
}
I get what I want :
Box initialized
Setup Complete
If I get rid of Box constructor class and instead do
void Box::init(Debug &debug){
this->debug = debug;
// Switches
pinMode(28, INPUT_PULLUP);
debug.message("Box intialized");
debug.line();
}
Called via Main.ino like
void setup(){
debug.init();
box.init(debug);
debug.message("Setup Complete");
debug.line();
}
I get the desired response again. I don't understand why my first attempt doesn't work nor do I feel comfortable knowing what best practices are. I would appreciate any guidance.
You have two Debug values in your code. One global, one member of the Box class.
Those are two distinct values, since Box create or copy from a value to create its own, and there's the global one.
A solution would be to contain a reference or a pointer.
Here's the example with a reference:
class Box {
private:
Debug& debug;
// ^---- there
public:
Box(Debug &debug);
void init();
};
If you want Box to still be assignable, then use a pointer:
class Box {
private:
Debug* debug;
// ^---- now it's a star
public:
Box(Debug &debug);
void init();
};
Box::Box(Debug &debug):
debug(&debug)
{} // ^----- here, we take the address of the debug variable.
Since references are immutable, you loose some important feature of the language: assignment.
struct thing {
int& ref;
};
int main () {
int a, b;
thing t1{a}, t2{b};
t1 = t2; // ERROR!
}
The assignment would cause t1.ref to point to b after the assignment.
Pointer has a more difficult syntax and hard to guess semantics. However, they play very well with assignment since they give you more freedom:
struct thing {
int* ptr;
};
int main () {
int a, b;
thing t1{&a}, t2{&b};
t1 = t2; // Works, t1.ptr points to b
}

Singleton class throws C2653 error: is not a class or namespace name

App.h:
#ifndef APP_H
#define APP_H
#include <SFML/Graphics.hpp>
#include <vector>
#include "RoomManager.h"
typedef unsigned int uint;
class App {
private:
sf::RenderWindow window;
sf::Event evt;
uint screen_width = 0;
uint screen_height = 0;
sf::Clock deltaClock;
float deltaTime = 0.0f;
RoomManager& roomManager = RoomManager::GetInstance();
std::vector<sf::Sprite> allDrawables;
App() { }
~App() { }
public:
static App& GetInstance() {
static App instance;
return instance;
}
void CreateWindow(uint width, uint height) {
screen_width = width;
screen_height = height;
window.create(sf::VideoMode(screen_width, screen_height), "Point'n'click adventure");
}
void Update() {
while (window.isOpen()) {
deltaTime = deltaClock.restart().asSeconds();
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::EventType::Closed)
window.close();
}
Draw();
}
}
void ResizeScreen(uint width, uint height) {
screen_width = width;
screen_height = height;
window.setSize(sf::Vector2u(screen_width, screen_height));
}
void AddDrawable(sf::Sprite& sprite) {
allDrawables.push_back(sprite);
}
void Draw() {
window.clear();
for (int i = 0; i < allDrawables.size(); i++) {
window.draw(allDrawables[i]);
}
window.display();
}
};
#endif
DrawableEntity.h:
#ifndef DRAWABLEENTITY_H
#define DRAWABLEENTITY_H
#include <SFML/Graphics.hpp>
#include "App.h"
class DrawableEntity {
private:
sf::Texture backgroundTexture;
sf::Sprite backgroundSprite;
public:
DrawableEntity() {
App::GetInstance().AddDrawable(backgroundSprite);
}
~DrawableEntity() { }
void LoadTexture(const std::string texturePath) {
backgroundTexture.loadFromFile(texturePath);
backgroundSprite.setTexture(backgroundTexture);
}
};
#endif
RoomManager.h:
#ifndef ROOMMANAGER_H
#define ROOMMANAGER_H
#include <SFML/Graphics.hpp>
#include <vector>
#include "Room.h"
class RoomManager {
private:
std::vector<Room> rooms;
public:
static RoomManager& GetInstance() {
static RoomManager instance;
return instance;
}
void AddRoom(Room room) {
rooms.push_back(room);
}
};
#endif
Room.h:
#ifndef ROOM_H
#define ROOM_H
#include <SFML/Graphics.hpp>
#include "App.h"
#include "DrawableEntity.h"
class Room {
private:
DrawableEntity background;
public:
Room(const std::string backgroundTexturePath) {
background.LoadTexture(backgroundTexturePath);
}
~Room() { }
};
#endif
main.cpp:
#include <SFML/Graphics.hpp>
#include "App.h"
using namespace sf;
int main() {
App& app = App::GetInstance();
RoomManager& roomManager = RoomManager::GetInstance();
app.CreateWindow(1920, 1080);
roomManager.AddRoom(Room("room_0_background.jpg"));
app.Update();
return 0;
}
My idea here is that whenever I would create DrawableEntity object, it would automatically add its sprite to allDrawables vector in App. The above code throws me C2653 error saying that "'App' is not a class or namespace name". The error appears in DrawableEntity() constructor, at line where I call AddDrawable() method. It's been a while since I coded in C++ (now I code mostly in C#) and I'm not sure how to fix this.
[Note: As, you haven't shared DrawableEntity() constructor code(I didn't find any) I am assuming your problem might be the following. If the following solution does not solve your issue, please share DrawableEntity() constructor code.]
You must have called AddDrawable() as following:
App& appInstance = App::GetInstance();
appInstance::AddDrawable(); // it is wrong
You shouldn't call like above
Rather do the following:
App& appInstance = App::GetInstance();
appInstance.AddDrawable(); // it is correct
Edit(Possible solution, this must be happening in your code):
I guess #drescherjm is right. Please, take a careful look at the code snippets below. I have tested some codes similiar like your code structure:
so_test.cpp file:
#include <cstdio>
#include "so_header.h"
int main() {
A& objA = A::getInstance();
int xa = objA.getX();
printf("xa: %d\n", xa);
B& objB = B::getInstance();
int xb = objB.getX();
printf("xb: %d\n", xb);
return 0;
}
so_header.h file:
#ifndef CLASS_A
#define CLASS_A
#include <cstdio>
#include "so_header_2.h"
class A {
private:
int x = 100;
A(){}
public:
static A& getInstance() {
static A obj;
return obj;
}
int getX() {
return x;
}
void print() {
B& objB = B::getInstance();
int xb = objB.getX();
printf("xb: %d\n", xb);
}
};
#endif
so_header_2.h:
#ifndef CLASS_B
#define CLASS_B
#include <cstdio>
#include "so_header.h"
class B {
private:
int x = 200;
B(){}
public:
static B& getInstance() {
static B obj;
return obj;
}
int getX() {
return x;
}
void print() {
A& objA = A::getInstance();
int xa = objA.getX();
printf("xa: %d\n", xa);
}
};
#endif
When I compile so_test.cpp, I get the follwowing error(using mingw compiler):
In file included from so_header.h:6:0,
from so_test.cpp:2:
so_header_2.h: In member function 'void B::print()':
so_header_2.h:21:3: error: 'A' was not declared in this scope
A& objA = A::getInstance();
^
so_header_2.h:21:6: error: 'objA' was not declared in this scope
A& objA = A::getInstance();
^
so_header_2.h:21:13: error: 'A' is not a class, namespace, or enumeration
A& objA = A::getInstance();
The reason is in print function of A, A is calling B and in print function of B, B is calling A.
Your code structure follows a similiar pattern. Let's start from DrawableEntity.
> DrawableEntity calls App
> App calls RoomManager
> RoomManager calls Room
> Room calls App and DrawableEntity(notice, the order here. App is called before DrawableEntity, and so loop has come back to App)
> App calls RoomManager...and ...so on...
So, the loop is:
DrawableEntity -> App -> RoomManager -> Room -> App -> RoomManager -> ...
As, App is the start of the loop or the first object in the loop to be called, you're getting error recognizing "App" class...cause, you started declaring App, but you've never finished declaring it, and in the middle of declaring it, you are trying to use it. So, you're basically trying to use something that hasn't even seen the light of existence(An analogy could be: its still in womb, not born yet...).
This has happended with your code.
To solve your problem, you need to reorganize your code structure a bit. Just break the cycle(i.e. loop) of call dependency, and you'd be okay.

error: using-declaration for non-member at class scope using std::cout

I downloaded a c++ project and was able to compile it using a makefile generated by cmake.
However when I try to add my own series of .h files in one of the .hh files of the project I start to get a million of errors, one of them being:
error: using-declaration for non-member at class scope
using std::cout;
When the .h file that contains
using std::cout is used elsewhere it works, but when added to this project it gives this error.
What can be the problem?
using std::cout;
using std::endl;
class TextManager : public FileManager {
public:
TextManager (const char * filename);
void scanFile (Image &image, Scene &scene);
void scanObjectModel (Image &image, Scene &scene);
void getImageData (Image &image);
void getMaterialData (Scene &scene);
void getLightData (Scene &scene);
void getSphereData (Scene &scene);
void getPlaneData (Scene &scene);
void getTriangleData (Scene &scene);
int getLineValue (int size);
void getLineValue2 (float (&lineNumbers) [10], Scene &scene, int &lineNumbersIndex);
void getVerticesValues (int initPos, Scene &scene);
private:
std::string line;
float fractionaryTenPowers [6];
};
Problem solved. Was the lack of a bracket to close the declaration of one of the classes that was causing it.
The error means you've done this:
struct Foo {
using std::cout;
...
};
That's not valid C++, in a class body you can only add a using-declaration for members of base classes, not arbitrary names.
You can only add using std::cout at namespace scope or inside a function body.
You can put it in the class as long as you put it under the public or private sections.
#include <iostream>
namespace CoolNamespace
{
struct AnotherReallyLongClassName
{
int a = 75;
};
struct SomeReallyLongClassName
{
int a = 42;
};
} // namespace CoolNamespace
class Widget
{
// You can't do this though!
// using ShorterName = CoolNamespace::SomeReallyLongClassName;
public:
// You can use a using statement inside of a class!
using ShorterName = CoolNamespace::SomeReallyLongClassName;
ShorterName foo;
int get_another_name()
{
return bar.a;
}
private:
// You can do it here also!
using AnotherName = CoolNamespace::AnotherReallyLongClassName;
AnotherName bar;
};
int main()
{
Widget widget;
std::cout << widget.foo.a << std::endl;
// Also, if you can reference public using statements from the class definition.
Widget::ShorterName thing;
std::cout << thing.a << std::endl;
// But you can't do this because it's private.
// Widget::AnotherName name;
return 0;
}
Indeed, check if you have one open bracket in one of the member functions in the class declaration.
I did this in .h file;
class foo{
void cat();
void bar{
void dog();
}
in .cc file I defined the member functions
void foo::cat(){
std::cout<<"This is cat"<<std::endl;
}
void foo::bar(){
std::cout<<"hello"<<std::endl;
}
void foo::dog(){
std::cout<<"meow"<<std::endl;
}
But notice I used { instead of; for member function bar in .h file. That's causing the error. (At least for me).