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
};
Related
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'm attempting to create a text-based RPG for my Adv. Programming course and I'm a bit unsure about the polymorphism. I'm building this in pieces and currently I'm trying to get a visual display going based on a prior assignment that involved drawing colored characters to the console via coordinates to create a map. So I have this main:
#include "Map.h"
using namespace std;
int main()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
ColorMap* _map = new ColorMap(handle, "north");
}
and I want to point to the base class's function populateMap, and then access the derived class's populateMap. Here is the header for reference
#pragma once
#include <Windows.h>
#include <string>
using namespace std;
class Map
{
public:
Map(HANDLE handle, string direction);
~Map(){};
virtual void update();
virtual void populateMap();
void drawPoint(int x, int y) const;
protected:
HANDLE mHandle;
char mMap[15][15];
char mWall;
char mSpace;
string mIncomingDirection;
};
class ColorMap : public Map
{
public:
ColorMap(HANDLE handle, string direction);
~ColorMap(){};
virtual void update();
virtual void populateMap();
void drawMap();
private:
int mColor;
};
It isn't clear where you want to access the base class' method, but you can do this:
_map->Map::populateMap(); // calls base class member function
_map->populateMap(); // calls derived class member function
if you need ColorMap implementation to extend the base implementation: Your ColorMap's populateMap() implementation should go:
void ColorMap::populateMap() {
Map::populateMap(); // first call the base class
// now do your things...
}
If you have
Map *m=new ColorMap(...);
m->populateMap();
That will call the derived class method.... However from within that method you can still access the parent class version of the method and run it (before, after or in-between) the rest of the code.
Have your Colormap constructor pass the arguments to the base constructor.
Once virtual delared in base class, derived classes don't need to declare virtual again.
I want to transfer a function pointer in the constructor but get some error Messages...
I my parent class I declared:
class Strip{
public:
typedef void(Strip::*LOG)(const std::string&);
with a function log(const string&)
In my child class I forward declare Strip with class Strip and have somthing like that
class Observable{
public:
Observable(const char &signal,Strip::LOG log,const QCustomPlot *plot);
with a parameter
Strip::LOG log;
When I try to compile I get the error's
Strip::LOG has not been declared
and LOG in class Strip does not name a type
Any Idea how to fix that?
So passing a pointer to a member function presents several issues:
It's a member function as such it will need to have an instance of the class passed into it to work (the implicit this parameter).
It doesn't prevent the class you're passing it to from knowing about the class the function pointer originates so you gain nothing in terms of hiding.
A better way is to declare an Interface and pass that
// ILogger.hpp
// should be completely virtual
struct ILogger{
virtual void log(const ::std::string&) = 0;
};
// Strip.cpp
class Strip : public ILogger{
public:
void log(const ::std::string& data){
// does something
}
};
// Observable.cpp
#include "ILogger.hpp"
class Observable{
public:
Observable(ILogger* logger);
};
// some other file that knows about and constructs both
// has to be a pointer allocated to new to make the Vtables work
::std::unique_ptr<Strip> s(new Strip());
// pass in the pointer to an instance of a class that implements ILogger
Observable observed(s.get());
Using an interface means you can completely abstract the two classes apart and Observable need not know anything about the instance being passed to it other than it implements ILogger. Internally Observable can call the logger by just calling logger->log.
May be this code can be usefull (compiled w/o errors):
#include <iostream>
using namespace std;
class Strip{
public:
typedef void(Strip::*LOG)(const std::string&);
void log(const string& s)
{
cout << "log() called\n";
}
};
class Observable{
public:
Observable( Strip::LOG l )
{
Strip s;
(s.*l)("string");
}
};
int main() {
Strip::LOG log = &Strip::log;
Observable o( log );
return 0;
}
http://ideone.com/RD4K1r
I'm new to C++ and i'm having a hard time figuring out what's wrong with my virtual functions. So, here's what i have:
GEntity.h
class GEntity
{
public:
//...
virtual void tick(void);
virtual void render(void);
//...
};
GEntity.cpp
//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...
GLiving.h
class GLiving : public GEntity
{
public:
//...
virtual void tick(void);
virtual void render(void);
//...
};
GLiving.cpp
//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...
Then i have other classes that derive from GLiving (Player, Enemy) which implement their own versions of this two methods:
Player.h
class Player : public GLiving
{
public:
//...
void tick(void);
void render(void);
//...
};
Player.cpp
//...
void GEntity::tick(void)
{
//Here there's some actual code that updates the player
}
void GEntity::render(void)
{
//Here there's some actual code that renders the player
}
//...
Now, if i declare an object of class Player, and call the render/tick method, everything goes well, but i am in a situation in which i add my player to an arraylist (a struct i created) of GEntity, and then, when i get it back, i get it as a GEntity, and i need to call the render/tick methods without knowing it's derived class...
I've tried with the code above, but i get an access violation in the line where i call either the render or tick method, on the extracted GEntity...
...is what i want even possible to achieve?
(sorry if my english is not so good, but i'm italian)
If you have an array of GEntity then, each time you "add" a derived type, the equivalent of this happens:
GEntity g;
Player p;
g = p; // object slicing, you assigned a Player to a GEntity object.
g.render(); // GEntity::render() gets called
On the other hand, you can use a pointer to a base class to access a derived method:
GEntity* g;
Player p;
g = &p;
g->render(); // calls Player::render()
So a way to deal with polymorphism in containers is to have arrays/containers of (preferably smart) pointers to the base class. This example uses raw pointers for simplicity, but you should use smart pointers in real code:
std::vector<CEntity*> entities;
entities.push_back(new Player);
entities.push_back(new GLiving);
// some c++11
for ( auto e : entities) {
e->render();
}
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.