I can't get method overriding to work. Right now I have a class called Sprite, and two subclasses; Let's call them Goomba and Koopa. Instances of Koopas and Goombas are stored in an std::list of sprites called spriteList, and an iterator goes through this list and calls each sprite's behave() function.
I can get this to work with Goombas alone, by defining the behavior function as Sprite::behave(). But if I try to do the same thing with Koopas, the compiler gets mad because Sprite::behave() is already defined in Goomba. What am I doing wrong? I get the feeling that the answer is an extremely simple syntax issue, but looking online yielded no examples that looked quite like my code.
I'll paste some code, hopefully it'll help. This isn't my exact source code, so I apologize for any typos.
//Sprite.h:
#ifndef SPRITE_H
#define SPRITE_H
class Sprite {
private:
float xPosition; float yPosition;
public:
Sprite(float xp, float yp);
void move(float x, float y); //this one is defined in Sprite.cpp
void behave(); //this one is NOT defined in Sprite.cpp
};
#endif
//Goomba.h:
#ifndef GOOMBA_H
#define GOOMBA_H
#include "Sprite.h"
class Goomba : public Sprite {
public:
Goomba(float xp, float yp);
void behave();
};
#endif
//Goomba.cpp:
#include "Goomba.h"
Goomba::Goomba(float xp, float yp): Enemy(xp, yp) {}
void Sprite::behave(){
Sprite::move(1, 0);
}
//Koopa.h looks just like Goomba.h
//Koopa.cpp
#include "Koopa.h"
Koopa::Koopa(float xp, float yp): Enemy(xp, yp) {}
void Sprite::behave(){
Sprite::move(-2, 1);
}
In Sprite you have to declare the function as virtual
virtual void behave();
Then in Goomba you should state that you are going to override that function
virtual void behave() override;
Note: The override keyword is new as of C++11
In both Koopa.cpp and Goomba.cpp you are defining Sprite::behave. This results in two definitions, as your toolchain told you. You want to define Koopa::behave and Goomba::behave, respectively, in those files.
You also want to define Sprite::behave in Sprite.cpp (you said you currently do not define it anywhere).
You will also want to make Sprite::behave a virtual function in order to get the polymorphic behavior you are after working the way you likely expect it to:
class Sprite {
// ...
// You can either define Sprite::behave in Sprite.cpp or change the declaration to:
// virtual void behave() = 0;
// to make it "pure virtual," indicating that subclasses must provide an implementation.
virtual void behave();
};
In Goomba.cpp, for example:
#include "Goomba.h"
Goomba::Goomba(float xp, float yp): Enemy(xp, yp) {}
void Goomba::behave(){
...
}
Related
I got error say [Error] extra qualification 'bezierCurve::' on member 'calCurve' [-fpermissive]. Could anyone explain to me why this happen? I've been looking for answer, but the I cannot solve the problem.
#ifndef _BEZIERCURVE_H_
#define _BEZIERCURVE_H_
#include "bezier.h"
class bezierCurve : public bezier{
private:
int numPoints;
float **controlPoints;
float **curvePoints;
void bezierCurve::calCurve(); //and error here
public:
bezierCurve(int numPoints, float *points[3]);
void bezierCurve::setShowPoints(bool showControlPoints); // I got the error here
virtual void draw();
~bezierCurve();
};
#endif
This is an error because it is not valid C++ syntax. The elephant in the room is that VisualC++ has historically not considered this an error. But GCC has since around version 4.
Simply removing the extra qualifications fixes the code.
For example:
#ifndef __ANIMAL_H__
#define __ANIMAL_H__
class Animal
{
...
int Animal::getLegCount();
bool Animal::hasFur();
};
#endif
Is not correct, member must be defined without the Classname:: prefix:
#ifndef __ANIMAL_H__
#define __ANIMAL_H__
class Animal
{
...
int getLegCount();
bool hasFur();
};
#endif
You are confusing declarations and definitions. When you declare a member function, it's in the context of the class already so classname:: is redundant. When you define the body of a function outside of the class, you need the classname:: so that the compiler knows which class it belongs to.
class bezierCurve : public bezier{
void setShowPoints(bool showControlPoints);
};
void bezierCurve::setShowPoints(bool showControlPoints) {
}
this is what output i get. suppose it's not like this.
#kingsley, this shown the output when i'm running the codes after I remove _s from sscanf_s().
First: My English is not that good yours is. Excuse me.
I'm using Ubuntu (I don't know if this is important) and I had issues with Code::Blocks since I started to use it. But I fixed them by re-opening the program. But now, I get a really crazy error when compiling the code. I included a file just like usual:
#include "GameObjectUtility.h"
and I used the class "GameObjectUtility" to declare a member object, just like this:
class GameObject
{
std::vector<GameObjectUtility> uts;
// Error here:
// GameObjectUtility was not declared in this scope
}
So, is this my fault or is there something buggy with Code::Blocks?
And, additionally, is there a way of saying to the Linker: First execute this file and then the other?
Thank you for your answers!
EDIT: .h and .ccp file GameObjectUtility:
So this is GameObjectUtility.h:
#ifndef GAMEOBJECTUTILITY_H
#define GAMEOBJECTUTILITY_H
#include <string>
#include "Collision.h"
class GameObjectUtility
{
public:
GameObjectUtility();
virtual ~GameObjectUtility();
virtual void Update() = 0;
virtual void LateUpdate() = 0;
virtual void FixedUpdate() = 0;
static void SendMsg(std::string msg);
protected:
private:
virtual void GetMsg(std::string msg) = 0;
};
#endif // GAMEOBJECTUTILITY_H
And in GameObjectUtility.cpp are just two empty definitions of constructor and destructor
Since class GameObjectUtility is pure virtual, you cannot instantiate it.
You can only store std::vector<GameObjectUtility*> in class GameObject.
I keep having some weird errors while coding on C++ using SDL as my graphics library.
Today, I was starting to develop a game I wanna make, and suddenly a encountered a quite strange error.
#ifndef CREATURE_H_
#define CREATURE_H_
#include "SDL/SDL.h"
using namespace std;
class Creature
{
private:
SDL_Rect drawBox;
drawBox.x;
drawBox.y;
drawBox.h;
drawBox.w;
SDL_Surface *sprite;
public:
void spawn (SDL_Rect drawBox,SDL_Surface* screen);
bool isTouching (class object);
bool isAlive ();
void move (int x,int y);
bool isFalling ();
void setSprite ();
};
#endif
That's my creature.h header file, and the creature.cpp is empty (it can compile but it wont do anything interesting). So, I can see that SDL_Rect is a struct and all that,but then why won't the SDL_Rect's name be treated as a variable name when it is? See ya guys, and peace.
Removing the members from drawBox from the class declaration will do, if I wished to change the values of those members, I would have to create a Creature object. And that's about. Thanks everyone.
I am currently developing a c++ program with the main purpose being you have two different objects which float around the screen, crash into each other, etc.
Anyway the problem that I am having is that I need to derive two classes from my base class. However in the definition and declaration of my derived class I am getting an error and cant work it out. I have searched the net and sought advice from my colleagues however am unable to find the source of the problem. the code is
Jetsam(RandomNumber &rnd, Console &console);
(For the header file)
and
Jetsam::Jetsam(RandomNumber &rnd, Console &console): Element(rnd, console){};
(For the cpp file)
The error I am getting is IntelliSense:
Jetsam::Jetsam(RandomNumber &rnd, Console &console)" provides no initializer for: e:\c++\my game\my game\jetsam.cpp.
Does anyone have any idea of what is wrong. Any help would be much appreciated :)
Cheers guys, Alyn.
As requested:
JETSAM
#pragma once
#include "RandomNumber.h"
#include "Console.h"
#include "element.h"
#include <iostream>
using namespace std;
class Jetsam : public Element
{
public:
Jetsam(RandomNumber &rnd, Console &console);
~Jetsam();
void printAt(void);
protected:
RandomNumber &rnd;
Console &console;
};
Element
#pragma once
#include "RandomNumber.h"
#include "Console.h"
#include <iostream>
using namespace std;
// code shell, amend as appropriate
class Element
{
protected:
RandomNumber &rnd;
Console &console;
int x;
int y;
int energy;
int direction;
int speed;
char identifier;
static char nextIdentifier;
public:
Element();
Element(RandomNumber &rnd, Console &console);
// precondition: references to RandomNumber and Console objects are provided, along with any other desired parameters
// postcondition: Element object created and private members initialised
// example of use: Element element(rnd, console);
virtual void print(void);
// precondition: none
// postcondition: identifier, x and y are sent to the standard output
// example of use: element.print();
virtual void printAt(void)=0;
// precondition: none
// postcondition: text background is changed proportionate to its energy in the following order
// BLUE, GREEN, AQUA, YELLOW, RED, PURPLE, e.g. an object with 23 energy would have an AQUA background
// object's identifier is sent to the standard output at its x, y coordinates
// example of use: element.printAt();
int getX(void);
int getY(void);
int getEnergy(void);
int getDirection(void);
int getSpeed(void);
//getters for the base class
void setX(int);
void sety(int);
void setEnergy(int);
void setDirection(int);
void setSpeed(int);
//setters for the base class
};
The problem is that both the classes Element and Jetsam define these members:
RandomNumber &rnd;
Console &console;
This means each instance of Jetsam actually has two of these: Element::rnd and Jetsam::rnd. As they're references, they have to be initialised in the mem-initialiser list of the constructor; there's no other way to initialise them.
To simply fix the error, you'd have to do this:
Jetsam::Jetsam(RandomNumber &rnd, Console &console) :
Element(rnd, console)
, rnd(rnd)
, console(console)
{}
However, I suspect you don't really want them duplicated (especially since they're protected inside Element). So the correct solution would be to simply remove their declarations from Jetsam. After that, Jetsam would look like this:
class Jetsam : public Element
{
public:
Jetsam(RandomNumber &rnd, Console &console);
~Jetsam();
virtual void printAt(void);
};
Note that it's generally a good idea to repeat the virtual keyword when overriding virtual functions in derived classes (it helps readability), even though it's not required by the standard. Of course, with C++11 compilers which support it, override is even more preferable.
I am new to Stack Overflow and am teaching myself C++, but am still quite a beginner. After completing a nice chunk of the book I am using (which may be considered out dated and/or not a great book) I decided to re-enforce some concepts by trying them on my own, referencing the book only if needed, but I appear to be stuck. The concepts I am trying to tackle are inheritance, polymorphism, abstract data types (ADT), and separating the code for my classes into header files (.h) and C++ file (.cpp). Sorry in advance for the wall of text, I just want to be clear and specific where I need to be.
So, my goal is to create simple shape classes that inherit from one another where applicable. I have four classes: myPoly, myRectangle, myTriangle, and mySquare. myPoly, if I understood this concept correctly, should be an ADT since one of the methods is a pure virtual function (area method), since creating a myPoly object isn't something I would want a user of my classes to do. myRectangle and myTriangle both derive from myPoly and in turn mySquare derives from myRectangle. I've also included my test program where I planned on testing my classes. I am using Code::Blocks 10.05 and keep getting the following error when I build my test.cpp program:
undefined reference to 'myPoly::myPoly()'
I get 42 similar errors all for the methods of the myPoly class. This happens when I try to build the .cpp files for myRectangle and myTriangle too. With the research I tried to do on the problems I been running into with this little project I feel like something is wrong with my inclusion guards or my #include statements, and something isn't getting included properly or is getting included too many times. At first I was providing the .cpp file for myPoly to myRectangle and myTriangle, but read in a couple of places that including the .h file for myPoly is more efficient and some how automatically include its .cpp. If anyone can provide some insight on that, it would be greatly appreciated. I also remember something about how using quotes in your inclusion statements is different than using the angle brackets. Below are all nine files that I have made for my little project. Most of the comments are little notes or reminders to me.
myPoly.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//header file for Polygon class
#ifndef MYPOLY_H
#define MYPOLY_H
class myPoly
{
public:
//constructor
//const reference pass because the values w and h don't change and reference avoid the time it takes to copy large
// objects by value (if there were any)
myPoly();
myPoly(const float & w, const float & h);
//destructor
virtual ~myPoly();
//accessors
float getWidth();
float getHeight();
void setWidth(const float & w);
void setHeight(const float & h);
virtual float area() = 0;
private:
float width, height;
};
#endif
myPoly.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myPoly class
#include "myPoly.h"
//constructor
myPoly::myPoly()
{
setWidth(10);
setHeight(10);
}
myPoly::myPoly(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
//destructor
myPoly::~myPoly() {}
//accessors
float myPoly::getWidth() {return width;}
float myPoly::getHeight() {return height;}
void myPoly::setHeight(const float & w) {width = w;}
void myPoly::setWidth(const float & h) {height = h;}
//pure virtual functions have no implementation
//area() is handled in the header file
myRectangle.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myRectangle class
#ifndef MYRECTANGLE_H
#define MYRECTANGLE_H
#include "myPoly.h"
class myRectangle : public myPoly
{
public:
//constructor
myRectangle();
myRectangle(const float & w, const float & h);
//destructor
~myRectangle();
//this doesn't need to be virtual since the derived class doesn't override this method
float area();
};
#endif
myRectangle.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementaion file for the myRectangle class
//get a vauge compiler/linker error if you have virtual methods that aren't implemented (even if it ends up being just
// a 'stub' method, aka empty, like the destructor)
#include "myRectangle.h"
myRectangle::myRectangle()
{
setWidth(10);
setHeight(10);
}
myRectangle::myRectangle(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
myRectangle::~myRectangle()
{
}
float myRectangle::area()
{
return getWidth() * getHeight();
}
myTriangle.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myTriangle class
#ifndef MYTRIANGLE_H
#define MYTRIANGLE_H
#include "myPoly.h"
//imagine the triangle is a right triangle with a width and a height
// |\
// | \
// | \
// |___\
class myTriangle : public myPoly
{
public:
//constructors
myTriangle();
myTriangle(const float & w, const float & h);
//destructor
~myTriangle();
//since nothing derives from this class it doesn't need to be virtual and in turn neither does the destructor
float area();
};
#endif
myTriangle.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myTriangle class
#include "myTriangle.h"
myTriangle::myTriangle()
{
setWidth(10);
setHeight(10);
}
myTriangle::myTriangle(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
myTriangle::~myTriangle()
{
}
float myTriangle::area()
{
return getWidth() * getHeight() / 2;
}
mySquare.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for mySquare class
#ifndef MYSQUARE_H
#define MYSQUARE_H
#include "myRectangle.cpp"
class mySquare : public myRectangle
{
public:
//constructors
mySquare();
//explicity call the myRectangle constructor within this implementation to pass w as width and height
mySquare(const float w);
//destructor
~mySquare();
};
#endif
mySquare.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for mySquare class
#include "mySquare.h"
mySquare::mySquare()
{
setWidth(10);
setHeight(10);
}
mySquare::mySquare(const float w)
{
myRectangle::myRectangle(w, w);
}
mySquare::~mySquare()
{
}
test.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//main class that uses my shape classes and experiments with inheritance, polymorphism, and ADTs
#include "myRectangle.cpp"
//#include "mySquare.cpp"
#include "myTriangle.cpp"
#include <iostream>
int main()
{
myPoly * shape = new myRectangle(20,20);
return 0;
}
I am very curious as to why I am getting these errors or why something I did may not be considered good/best practice, as opposed to just receiving a line of code to make my errors go away.
Your inclusion guards look fine. If they were not, you would most likely get a compiler error, including file and line number information. The error you posted seems more like a linker error.
However, there is one "problem" with your code. As a general rule, you should only #include .h files and not .cpp files.
Now to get to the solution: I am unfamiliar with Code::Blocks myself. However, I hope I can give some general information that will point you in the right direction. Some compilers I have used in the past by default allowed me to compile a single C++ file and run the program. To compile a program with more than one file, I had to create a project. (Most modern compilers force you to create a project from the start.) With this in mind, I would suggest you check out how to create a project for your program in Code::Blocks.
From a code stand point (at least what I looked through), it looks pretty good, but:
There are two things to consider:
Don't directly include cpp files. For example, in mySquare.h, #include "myRectangle.cpp" should be #include "myRectangle.h". You want to be including the interface/declarations provided in the header file that tell the program how to make the class, not just the function definitions.
Second, make sure you're compiling with all your object files. I don't know code blocks, but if you were using g++ or something like that, you'd want to do g++ main.cpp myPoly.cpp mySquare.cpp etc. for all files. An error like this may happen if you forget myPoly.cpp, for example, because no definitions for its functions would be included.
Everything looks fine, actually. It is probably just as simple as not including myPoly.obj when you link your program. I am not familiar with Code::Blocks (although I know it's fairly popular) but I assume if you just, for example, click on test.cpp and choose "Run", that Code::Blocks will try to build a program from just that one source file. You'll need to include all the relevant source files in each program that you build.
Additionally to what the otehr guys said: You are not doing inheritance right...
When you do
class Poly
{
Poly();
~Poly();
}
class Rect : public Poly()
{
Rect();
~Rect();
}
You need to declare the child's constructor the following way:
Rect::Rect() : Poly()
{
}
The child must only be constructed after the father has finished constructing.