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.
Related
I'm making an app in React-native that uses Djinni from dropbox to bridge between C++ and Javascript. Calling from Javascript to C++ works well but now I'm implementing Call from C++ to Java/ObjC, my C++ skills are so and so. So I'm stuck on initialising class method.
I'm basing this on the example provided with Djinni.
AnotherClassMain is the access point from Javascript to C++.
I want to call runAProcess method from processAImpl inside anotherClassMain.
But I get the error
Field type 'aEditing::ProcessAImpl' is an abstract class
On the line ProcesAImpl processA; in anotherClassMain.hpp
How can I access this initiate the class processAImpl and call the runAProcess from anotherClassMain ??
// processA.hpp created by djinni
#pragma once
#include <string>
namespace aEditing {
class ProcessA {
public:
virtual ~ProcessA() {}
virtual bool runThisProcess(const std::string & str) = 0;
};
}
//processAImpl.hpp
#pragma once
#include "processA.hpp"
namespace aEditing {
class ProcessAImpl : public ProcessA {
public:
ProcessAImpl(const std::shared_ptr<ProcessA> & listener);
void runAProcess(const std::string aCommand);
private:
std::shared_ptr<ProcessA> aProcess;
};
}
//processAImpl.cpp
#include "procesAImpl.hpp"
namespace aEditing {
ProcessAImpl::ProcessAImpl (const std::shared_ptr<ProcessA> & listener) {
this->aProcess = listener;
}
void ProcessAImpl::runAProcess(const std::string aCommand) {
this->aProcess->runThisProcess(aCommand);
}
}
//anotherClassMain.hpp
#pragma once
#include "includes.hpp"
#include "processAImpl.hpp"
namespace anotherProcessing {
class AnotherProcessingMain: public anotherProcessing::AnotherProcessing {
public:
AnotherProcessingMain();
string anotherProcessing(const std::string &Input, const std::string &output) override;
private:
ProcesAImpl processA;
};
}
//anotherClassMain.cpp
#include "anotherClassMain.hpp"
namespace anotherProcessing {
shared_ptr<AnotherProcessing> AnotherProcessing::create() {
return make_shared<AnotherProcessingMain>();
}
AnotherProcessingMain::AnotherProcessingMain() {}
string AnotherProcessingMain::anotherProcessing(const std::string &Input, const std::string &output){
processA.runAProcess("testCommand"); //Trying to access this!
return "yeah";
}
How can I access this initiate the class processAImpl and call the runAProcess from anotherClassMain ??
I suppose you mean to instantiate the class processAImpl.
ProcessA is an abstract class because it contains a pure virtual function.
When you derive from an abstract class, you must implement that pure virtual function in the derived class. Otherwise you will not be able to instantiate the derived class.
So implement (provide a definition of) runThisProcess(const std::string & str) in the derived class processAImpl.
You are missing a declaration of the base classes pure virtual method bool runThisProcess(const std::string &). Did you mean for void ProcessAImpl::runAProcess(const string) to be the implementation?
The name and argument types must match exactly
runThisProcess vs runAProcess
const std::string & vs const string
You should mark the methods in the subclass that you intend to be overriding base class methods as override (if there can be grandchildren classes) or final (if there can't), so that the compiler can better inform you of typos like this
You are also missing initialisation of AnotherProcessingMain::processA. You need something like
AnotherProcessingMain::AnotherProcessingMain()
: processA(/* a const std::shared_ptr<ProcessA> & from somewhere */)
{}
because the only constructor for ProcessAImpl you defined takes a const std::shared_ptr<ProcessA> &.
It is very suspicious that you have ProcessAImpl have a std::shared_ptr<ProcessA> member. There needs to be some class that actually does stuff in it's runThisProcess member, and it should probably be ProcessAImpl. As it currently stands, ProcessAImpl does nothing. You've basically got turtles all the way down.
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'm new to C++ programming and I want to create two classes that have the exact same data members and functions. Is it possible to create two inherited classes that have the same data members/functions instead of making several duplicate methods for each class. I'm making a c++ game based on zork and I want to create two items, weapons and fruits. Both will take in a name as a string and a value as a double. Do I create the header file as below:
#ifndef ITEM_H_
#define ITEM_H_
#include <map>
#include <string>
#include <iostream>
using namespace std;
class Item {
private:
string description;
string longDescription;
float value;
public:
Item (string description, float inValue);
Item (string description);
string getShortDescription();
string getLongDescription();
float getValue();
void setValue(float value);
};
class Weapon:: public Item{
};
class Fruit:: public Item {
};
#endif /*ITEM_H_*/
How would I no go about creating the methods without duplicating them?
Do nothing for now. Both Weapon and Fruit are Items and contain all the members and methods that Item does.
Sooner or later, you'll want to specialize behaviour of child classes and the implementation of the method in the base class won't do it (if it's sensible to have an implementation in the first place). This is where polymorphism comes in. You'll make the method in the base class virtual and override it in the derived class:
class Item {
public:
virtual void Use() = 0; // pure virtual method
};
class Weapon : public Item {
public:
virtual void Use() override
{
Fire();
}
private:
void Fire() { /* do something */ }
};
Now when you have a reference or a pointer to the base class and you call Use on it, it'll dispatch to the corresponding method in the derived class.
EDIT: There's no way around "duplicating" constructors. Each class needs at least one if it is ever to be instantiated. Since you declared Item (string description, float inValue); you need to define it as a member of Item, too:
Item (string description, float inValue)
: description(description) // <-- avoid duplicating names of members in parameter list,
, value(inValue) // it does the right thing, but hurts readability
{ /* body empty */ }
If you need to call the constructor of the derived class with same parameters, you need to define another constructor and forward the arguments to the constructor of base class:
Weapon::Weapon(string desc, float val)
: Item(desc, val) { }
In C++11, there's a shortcut - you can inherit constructors and the compiler will generate these forwarding constructors for you:
class Weapon : public Item {
using Item::Item;
};
There's (unfortunately, perhaps) no way to specify which constructors you want to inherit. It's all or nothing.
Hope that helps.
you need to call constructor of parent class to assign value to description; and longDescription; like
class Weapon:: public Item{
Weapon(string description, float inValue):Item(description,inValue){}
Weapon(string description):Item(description){}
};
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();
}