I have a problem in MSVC++ 2008 where VS2008 is throwing this compile error:
error C2509: 'render' : member function not declared in 'PlayerSpriteKasua'
Now, what's confusing me is that render() is defined, but in an inherited class.
The class definition works like this:
SpriteBase -Inherited By-> PlayerSpriteBase -Inherited By-> PlayerSpriteKasua
So, a pared-down version of SpriteBase.h is the following:
class SpriteBase {
public:
//Variables=============================================
-snip-
//Primary Functions=====================================
virtual void think()=0; //Called every frame to allow the sprite to process events and react to the player.
virtual void render(long long ScreenX, long long ScreenY)=0; //Called every frame to render the sprite.
//Various overridable and not service/event functions===
virtual void died(); //Called when the sprite is killed either externally or via SpriteBase::kill().
-snip-
//======================================================
};
PlayerSpriteBase.h is this:
class PlayerSpriteBase : public SpriteBase
{
public:
virtual void pose() = 0;
virtual void knockback(bool Direction) = 0;
virtual int getHealth() = 0;
};
And finally, PlayerSpriteKasua.h is this:
class PlayerSpriteKasua : public PlayerSpriteBase
{
public:
};
I know there are no members in it yet, but that's simply because I hadn't gotten to adding them. Same goes for PlayerSpriteBase; there's other stuff left to go in to it.
The code in PlayerSpriteKasua.cpp is this:
#include "../../../MegaJul.h" //Include all the files needed in one go
void PlayerSpriteKasua::render(long long ScreenX, long long ScreenY) {
return;
}
void PlayerSpriteKasua::think() {
return;
}
int PlayerSpriteKasua::getHealth() {
return this->Health;
}
When I type, say, void PlayerSpriteKasua::, Intellisense pops up listing all the members of PlayerSpriteBase and SpriteBase just fine, but on compile it fails like I said above.
Is there any particular reason I'm getting this error?
PlayerSpriteBase.cpp is empty and has nothing in it as of yet.
SpriteBase.cpp has plenty of function definitions for SpriteBase, and uses the same format as PlayerSpriteKasua.cpp:
void SpriteBase::died() {
return;
}
is an example.
In PlayerSpriteKasua.h you need to re-declare whatever methods you're going to override/implement (without the "=0" to say that those methods are not abstract anymore). So you need to write it like follows:
class PlayerSpriteKasua : public PlayerSpriteBase
{
public:
virtual void think();
virtual void render(long long ScreenX, long long ScreenY);
virtual int getHealth();
};
...or did you omit that to keep your post shorter?
You need to provide a declaration for PlayerSpriteKasua::render() in your class definition. Otherwise, other translation units including your PlayerSpriteKasua.h wouldn't be able to tell that you'd provided a definition, and would be forced to conclude that PlayerSpriteKasua can't be instantiated.
You need to redeclare the members of SpriteBase that you are going to implement in PlayerSpriteKasua in the declaration of PlayerSpriteKasua in PlayerSpriteKasua.h.
Related
I use a library which has these definitions
typedef void (*CallbackFunction) (ESPRotary&);
void ESPRotary::setChangedHandler(CallbackFunction f) { ... }
When I try to use the setChangedHandler function I get an issue that the definition of my callback is wrong.
#pragma once
#include "ESPRotary.h"
class MyUsermod : public Usermod
{
private:
ESPRotary r = ESPRotary(13, 12);
public:
void rotate(ESPRotary &r)
{
Serial.println(r.getPosition());
}
void setup()
{
// argument of type "void (MyUsermod::*)(ESPRotary &r)" is incompatible
// with parameter of type "ESPRotary::CallbackFunction"C/C++(167)
r.setChangedHandler(rotate);
}
};
What am I doing wrong?
The callback function needs to be defined statically when defined inside the class:
class MyUsermod : public Usermod
{
private:
ESPRotary r = ESPRotary(13, 12);
public:
/* Callback function "static" defined */
static void rotate(ESPRotary &r)
{
Serial.println(r.getPosition());
}
void setup()
{
r.setChangedHandler(rotate);
}
};
References
Why callback functions needs to be static when declared in class?
void rotate(ESPRotary &r)
This is not a function. This is a (non-static) class method. This is declared as a member of class MyUsermod, something that's completely different from declaring a function named rotate() is some randomly-chosen .cpp file, with no further context.
Class methods require instances of classes to be invoked for. The type of rotate is
void (MyUsermod::*) (ESPRotary&)
and not
void (*) (ESPRotary&)
and this answers the reason for the compilation error, and the type mismathc.
As far as how to fix it, there is no uniform solution for every instance of this issue. It depends entirely on how these objects are used in the rest of your program. The most flexible solution is to change CallbackFunction to be the correct type, and then decide whose class instance's method will be invoked in the code that invokes the callback.
I'm trying to do class inheritance in C++, but it obviously works very differently than in Python.
Right now, I have two classes, one called Player that is the base class, and another one called HumanPlayer that's the subclass.
The Player class is an abstract class that has two ways of working.
The first is that it acts like a singleton. It has one static function called make_move that people can call with an int and a TicTacToeGame&, and it will make a move for the player with that int as the player's number in that game of TicTacToe.
The second is that it works as a class for creating objects that have a player number as a property. So, if you construct an object with the class, you should get back an object with a player_number property. Then, if you call the make_move function with just a TicTacToeGame& on the object, it will automatically plug in its player number and use the static class method to make the move in the game.
I want the same functionality for HumanPlayer, except I just want to have to write a new static function for HumanPlayer, and that's it, since the other functionality remains the same.
Here's the code:
#include <iostream>
#include <string>
using namespace std;
class TicTacToeGame {
};
class Player {
public:
static void make_move(int player_number, TicTacToeGame& game);
protected:
int player_number;
public:
explicit Player(int player_number_param) {
player_number = player_number_param;
}
public:
void make_move(TicTacToeGame& game) {
return make_move(player_number, game);
}
};
class HumanPlayer: public Player {
public:
static void make_move(int player_number, TicTacToeGame& game) {}
public:
HumanPlayer(int player_number_param): Player(player_number_param) {}
};
int main()
{
TicTacToeGame game;
HumanPlayer human_player = HumanPlayer(2);
human_player.make_move(game);
return 0;
}
I learned recently that subclasses don't inherit constructors, so it turns out I have to write both a new static function and a constructor, which I have done.
However, whenever I initialize a new HumanPlayer object, the compiler can't seem to find a match for the make_move(TicTacToeGame&) method, and I'm not sure why.
The specific error message I'm getting is
C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp: In function 'int main()':
C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp:41:29: error: no matching
function for call to 'HumanPlayer::make_move(TicTacToeGame&)'
human_player.make_move(game); ^ C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp:29:15: note: candidate:
static void HumanPlayer::make_move(int, TicTacToeGame&) static void
make_move(int player_number, TicTacToeGame& game) {} ^~~~~
C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp:29:15: note: candidate
expects 2 arguments, 1 provided
How can I get the HumanPlayer class to work in the same way the Player class does?
The redefinition of the static function with the same name is hiding the one you want to use.
Either rename it differently or add
public:
using Player::make_move;
Note that unlike Java you don't need to repeat public: before every function, the same visibility applies as long as you don't change it.
class YourClass {
public:
void foo1(); // public
void bar1(); // also public
protected:
void foo2(); // protected
void bar2(); // also protected
};
I am new to c++ and currently learning inheritance. I am not sure how to properly inherit my abstract class MapItem, I keep receiving these errors ..
error snippet
hidden overloaded virtual function 'MapItem::tick' declared here:
different qualifiers (const vs none)
virtual void tick() const = 0;
Undefined symbols for architecture x86_64:
"Residential::Residential()"
It is also claiming that my class Residential is an abstract class.
The program only successfully compiles and runs when I add the const keyword to the tick() function. But quiet obviously, this is a problem because tick() needs to operate on some class member variables.
I properly included all the files and my make file is targeting all the correct files, which makes this error out of my understanding.
map_item.h
// abstract class
class MapItem {
...
virtual void tick() const = 0;
}
residential.h
#ifndef RESIDENTIAL_H
#define RESIDENTIAL_H
#include "map_item.h"
class Residential : public MapItem {
private:
int capacity;
double taxRevenue;
public:
Residential();
virtual ~Residential();
void tick();
double collectTaxes();
};
#endif
residential.cpp
#include "residential.h"
Residential::Residential() {
capacity = 1;
taxRevenue = 0.0;
}
Residential::~Residential() {}
void Residential::tick() {
}
double Residential::collectTaxes() {
taxRevenue = 0.0;
return taxRevenue;
}
Your problem's simply that in Residential you declare and define tick as follows:
void Residential::tick()
...while the abstract base has...
virtual void tick() const = 0;
You should add the const to Residential::tick, or remove it from Mapitem::tick, so they're consistent. You say...
The program only successfully compiles and runs when I add the const keyword to the tick() function. This is a problem because tick() needs to operate on some class member variables.
...so it sounds like removing it is what you want to do.
It's also a good idea to add override to Residential::tick() so the compiler's obliged to verify that it matches MapItem::tick():
void Residential::tick() [const] override
Declaring a member method results in a function declaration that takes an implicit this pointer as a first parameter.
So a method void Residential::tick() (without the const at the end) results in a function like void Residential::tick(Residential* this).
Now adding the const at the end void Residential::tick() const can then be understood as a declaration with a const this pointer:
void Residential::tick(const Residential* this)
so, when you declare void Residential::tick() const in base class and then declare void Residential::tick() in derived class, the function signatures donot match and compiler throws an error.
So, decide which signature you need(const qualified/non const) and make sure both the signatures match.
I'm relatively new to c++ so I'm getting used to the scope of functions and variables in this environment. One issue I can't solve is being able to call a function defined in a subclass of a class which declares this function as pure virtual. Here's my class structure:
class Clock{
public:
virtual void Tick() = 0;
std::string Print();
//Mutators
int Seconds();
int Minutes();
int Hours();
void setTime(int secs, int mins, int hours);
//Accessors
int getSecs(){ return _secs; }
int getMins(){ return _mins; }
int getHrs(){ return _hours; }
private:
int _secs, _mins, _hours, _days = 0;
};
class NormalClock : public Clock{
public:
void Clock::Tick();
private:
};
class AlarmClock : public Clock{
public:
void Clock::Tick();
bool CheckAlarm();
void SetAlarmTime(int hrs, int mins, int secs);
int GetAHrs();
int GetAMins();
int GetASecs();
private:
int _alarmhrs, _alarmmins, _alarmsecs;
};
In my source file I want to define a body for the Tick() function in the AlarmClock class. But within this function I want to call the Tick() function from it's superclass, the NormalClock class. My issue is that when I do so without defining any objects to work off of, I can't call the superclass Tick() function as my IDE (VS2013) thinks I'm referring to the Tick()from the current class (the AlarmClock subclass). I looked around on the web and determined that it would probably require the use of the using keyword, but I've been unsuccessful in implementing it properly. Here's the function I'm trying to build for reference:
void AlarmClock::Tick(){
NormalClock::Clock::Tick();
if (this->CheckAlarm()){ cout << "\nAlarm! # " << this->Print() << "\n\n"; }
}
There's no errors in VS when calling the function as above, but the compiler complains of a static reference to a non-static member, which is understandable.
You were close, but your code has a few problems.
AlarmClock does not inherit from NormalClock
In AlarmClock::Tick call NormalClock::Tick() instead of NormalClock::Clock::Tick()
In NormalClock change Clock::Tick to Tick in your class declaration.
AlarmClock does not derive from NormalClock so you are calling the method statically (there is no instance of NormalClock to be used).
NormalClock::Clock::Tick();
looks a lot like you mean the right thing. Now make your AlarmClock actually inherit from NormalClock, and then just NormalClock::Tick() away :)
Thanks everyone, looks like it was a simple case of changing the base class declaration to NormalClockin the definition of the class AlarmClock. VS2013 was skipping over the NormalClock class and observing only the Tick() pure virtual function in Clock, which is why I couldn't call NormalClock::Tick() as intended in the body of the AlarmClock::Tick() function.
I have tried to answer this myself, by looking up several questions at StackOverflow. And although I think I understand this correctly, I can't fix this. Which, leaves me with the only obvious observation: I still don't get it.
I have made a summary of the questions at the bottom of this post, everything in between is information I have gathered and context for this question.
So, I get it that when you have a base class, and a derived class, your deconstructor should be marked virtual in the base class. To allow polymorphism.
But, I cannot seem to get my code to compile, or when it does compile, it does not link due 'undefined references'. I have been changing back and forth, but I never seem to get out of this cycle.
Basically I have an interace, defined like this:
#ifndef GUIELEMENT_H_
#define GUIELEMENT_H_
class GuiElement {
public:
virtual ~GuiElement();
virtual void draw() = 0;
};
#endif /* GUIELEMENT_H_ */
I have several objects extending from this. A simple relation is GuiWindow (directly derives from GuiElement):
#ifndef CGUIWINDOW_H_
#define CGUIWINDOW_H_
#include <assert.h>
#include <cstddef>
#include "../GuiElement.h"
#include "../GuiInteractionDelegate.h"
class GuiWindow : public GuiElement {
public:
GuiWindow(GuiInteractionDelegate * guiInteractionDelegate) {
assert(guiInteractionDelegate);
interactionDelegate = guiInteractionDelegate;
}
~GuiWindow() {
//delete interactionDelegate;
}
// called each frame, delegates its behavior to the given concrete cGuiWindowDelegate class.
void interact() {
interactionDelegate->interact(this);
}
private:
GuiInteractionDelegate * interactionDelegate;
};
#endif /* CGUIWINDOW_H_ */
This code does not link, gives me:
undefined reference to `GuiElement::~GuiElement()'
I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?
The next thing, which is really bugging me, is that I also have an abstract class derived from GuiElement, and concrete implementations on top of that. Basically giving:
GuiElement->GuiShape->GuiButton
Here is the header of GuiShape:
#ifndef GUISHAPE_H_
#define GUISHAPE_H_
#include "../GuiElement.h"
#include "../../gameobjects/Rectangle.h"
class GuiShape : public GuiElement {
public:
GuiShape(Rectangle * rect);
GuiShape(int x, int y, int width, int height);
~GuiShape();
void draw();
void setX(int value) { rectangle->setStartX(value); }
void setY(int value) { rectangle->setStartY(value); }
Rectangle * getRectangle() { return rectangle; }
bool isMouseOverShape();
void setColors(int darkBorder, int lightBorder, int inner);
int getDarkBorderColor() { return darkBorderColor; }
int getLightBorderColor() { return lightBorderColor; }
int getInnerColor() { return innerColor; }
protected:
Rectangle * rectangle;
private:
bool rectangleOwner;
int darkBorderColor;
int lightBorderColor;
int innerColor;
};
And finally GuiButton:
#ifndef CGUIBUTTON_H_
#define CGUIBUTTON_H_
#include <sstream>
#include <string>
#include "allegro.h"
#include "../../gameobjects/Rectangle.h"
#include "GuiShape.h"
class GuiButton : public GuiShape {
public:
GuiButton(Rectangle * rect, std::string theLabel);
GuiButton(int x, int y, int width, int height, std::string theLabel);
~GuiButton();
void draw();
std::string * getLabel() {
return label;
}
BITMAP * getBitmap() { return bitmap; }
void setBitmap(BITMAP * value) { bitmap = value; }
void setHasBorders(bool value) { hasBorders = value; }
void setPressed(bool value) { pressed = value; }
bool shouldDrawPressedWhenMouseHovers() { return drawPressedWhenMouseHovers; }
bool shouldDrawBorders() { return hasBorders; }
void setDrawPressedWhenMouseHovers(bool value) { drawPressedWhenMouseHovers = value; }
bool isPressed() { return pressed; }
private:
std::string * label;
bool drawPressedWhenMouseHovers;
bool hasBorders;
bool pressed;
BITMAP * bitmap;
void drawBackground();
void drawLighterBorder();
void drawDarkerBorder();
void drawButtonUnpressed();
void drawButtonPressed();
};
#endif /* CGUIBUTTON_H_ */
Which leads me to the following questions:
What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
Why would I get 'undefined references' with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)
Thanks in advance for your help!
What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
mark the base's (or all) destructor as virtual.
Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
Not sure what you mean by "concrete virtual" but a class with members that need destroying should destroy them in it's own destructor. No exceptions. when ~C is called, it destroys it's own stuff, and then ~B will be called automatically. The virtual just makes absolutely sure that ~C is called first.
Why would I get 'undefined references' with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)
virtual ~GuiElement(); tells the compiler that the class has a destructor that will be defined later. You wanted either:
// There is no definition, cannot make a local "GuiElement" variable
// They can only make local "GuiButton" or other derived.
// You can still have pointers to a GuiElement.
// This is called "pure virtual"
virtual ~GuiElement() = 0;
or:
// There is a definition, someone can make a local "GuiElement" variable
virtual ~GuiElement() {};
I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?
No. A virtual function (that is not pure virtual, as your destructor of GuiElement) must be defined if it is declared in the class.
Destructors go even further: they must be implemented, always, even if it is pure virtual[1]. If you hadn't declared it, the compiler would create one (implicitly nonvirtual, but would be virtual if it would override a virtual destructor) for you. In C++11, you can just mark it "defaulted" (which means "compiler, implement that for me") and "deleted" which means "the program may never, implicitly or explicitly, destruct objects of this type".
What is the best way to use virtual deconstructors where objects are derived from A->B-
C ?
You usually want to make the topmost base's destructor virtual, that means all destructors in the hierarchy are virtual.
And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
In ~B(), naturally.
[1] :
12.4/7: A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any
derived class are created in the program, the destructor shall be defined. If a class has a base class with a
virtual destructor, its destructor (whether user- or implicitly- declared) is virtual.