A better way to call child method from parent object - c++

I wish to call a child method in a perent method from a map that givied from a child's method. Basically the child gives the functions and the parent call them.
How can I use class child methods instead of static methods (see function 'login')? I try to call with pointers, but that didn't go so well.
And it is possible that the function 'optionsMap' would not create a new object every time the function is called, initialize the map only ones.
perent object:
typedef RequestResult(*handleRequestFunc)(IRequestHandler* self, RequestInfo what);
typedef std::map<unsigned char, handleRequestFunc> handleRequestFunc_map;
class IRequestHandler
{
public:
virtual handleRequestFunc_map optionsMap() = 0;
RequestResult handleRequest(RequestInfo requestInfo)
{
auto funcMap = this->optionsMap();
auto code = requestInfo.buffer.getCode();
auto func = funcMap.find(code);
if (func == funcMap.end())
{
// error
}
else
{
auto funcPointer = func->second;
return funcPointer(this, requestInfo);
}
}
};
child object:
class RequestHandlerFactory;
class LoginRequestHandler : public IRequestHandler
{
public:
RequestResult static login(IRequestHandler* self, RequestInfo what)
{
LoginRequestHandler* myself = (LoginRequestHandler*)(self);
// use myself
return RequestResult();
}
// Inherited via IRequestHandler
virtual handleRequestFunc_map optionsMap() override
{
handleRequestFunc_map returnMap;
returnMap[0] = &LoginRequestHandler::login; // function example
return returnMap;
}
}

Related

Why calling parent's method works on all its children instances?

I have a parent class in C++ with a method and declared two instances of its children classes. When I call this method on one child instance it makes changes to both children. Why is that, how to correct this?
Code is a bit too complicated to copy here, but I call this first child's method in other function where I move the instance of the child by pointers (first I receive it from other function by pointers too), so maybe there is something wrong with that.
[EDIT]
//Parent class:
class TWPerson : public TWObject
{
public:
...
void MakeDamage(int DamagePoints); //Function that causes problem
...
};
void TWPerson::MakeDamage(int DamagePoints)
{
LifePoints -= DamagePoints;
}
//Child class:
class TWSoldier : public TWPerson
{
...
public:
void Create(int SoldierID);
...
};
void TWSoldier::Create(int SoldierID)
{
UnitID = SoldierID;
LifePoints = 120;
IsAlive = true;
}
//Class that stores and uses arrays of TWSoldier class:
class TWArmy
{
private:
TWSoldier *InfantryDivision;
public:
TWSoldier* GetUnitPtrByID(int UnitID);
TWSoldier* CreateInfantryDivision();
};
TWSoldier* TWArmy::GetUnitPtrByID(int UnitID)
{
for (int SoldierNumber=0; SoldierNumber < SoldiersInitialNumber; SoldierNumber++)
{
if (InfantryDivision[SoldierNumber].GetUnitID() == UnitID)
{
return &InfantryDivision[SoldierNumber];
}
}
}
TWSoldier* TWArmy::CreateInfantryDivision()
{
static TWSoldier NewInfantryDivision[SoldiersInitialNumber];
for (int SoldierNumber = 0; SoldierNumber < SoldiersInitialNumber; SoldierNumber++)
{
IncreaseUnitID();
NewInfantryDivision[SoldierNumber].Create(CurrentUnitID);
}
return NewInfantryDivision;
}
//Class that gets TWSoldier* from two instances of TWArmy and conducts the problematic method:
class TWGameMode
{
private:
TWArmy AIArmy; // First instance of TWArmy that stores TWSoldier
TWArmy PlayerArmy; // Second instance of TWArmy that stores TWSoldier
public:
...
auto ReceivePlayerAttackCoordinates();
void PerformPlayerAttack();
void PerformAttack(TWSoldier* AttackingUnit, TWSoldier* AttackedUnit);
...
};
auto TWGameMode::ReceivePlayerAttackCoordinates()
{
struct Coordinates { // Declare a local structure
TWSoldier *OwnUnit, *OponentUnit;
};
int PlayerUnitID, AIUnitID;
...
TWSoldier* PlayerUnit = PlayerArmy.GetUnitPtrByID(PlayerUnitID);
TWSoldier* AIUnit = AIArmy.GetUnitPtrByID(AIUnitID);
return Coordinates{PlayerUnit, AIUnit};
}
void TWGameMode::PerformAttack(TWSoldier* AttackingUnit, TWSoldier* AttackedUnit)
{
... // RandomNumber and others calculated here
if (RandomNumber < AttackingUnitAimCapability)
{
AttackedUnit->MakeDamage(AttackingUnitDamage * AttackedUnitDefence);
}
...
}
I exaplained some stuff in comments in the code but also quick summary:
TWPerson is the parent class of TWSoldier with a method MakeDamage. TWArmy has array of TWSoldier class instances. There are two different instances of TWArmy (PlayerArmy and AIArmy) in class TWGamemode. Class TWGamemode receives pointers to two different TWSoldiers from different TWArmies and calls MakeDamage method on one of them (AttackedUnit which is a TWSoldier* of AIArmy instance) but changes of this method are visible on the same soldiers in both PlayerArmy and AI
Army arrays of TWSoldiers.
Let me know if you would need some additional information or I missed something.

How to add functionality from combination of different derived class?

I have multiple handlers derived from base Handler class which can do single data updates individually.
For eg.
class Handler {
public:
Data_t dbdata_;
public:
virtual void updateFlags() = 0;
}
class AHandler: public Handler {
.....
public:
void updateFlags() { dbdata_.flagA = 1; }
}
class BHandler: public Handler {
.....
public:
void updateFlags() { dbdata_.flagB = 1; }
}
class CHandler: public Handler {
.....
public:
void updateFlags() { dbdata_.flagC = 1; }
}
Individual handlers are called based on input flags in request. If request contains multiple flags, then in this case I want to try to avoid creating additional 6 handlers individually like following.
class ACHandler: public Handler {
.....
public:
void updateFlags() { dbdata_.flagA = 1; dbdata_.flagC = 1; }
}
class ABCHandler: public Handler {
.....
public:
void updateFlags() { dbdata_.flagA = 1; dbdata_.flagB = 1; dbdata_.flagC = 1 }
}
Main function code will be something similar to this.
void process(Request_t *request)
{
Handler *handler;
if (request->flagA)
handler = new AHandler();
else if (request->flagB)
handler = new BHandler();
....
...
handler->updateFlags();
}
Is there a better way to approach this problem, by re-writing how the handlers are connected to each other ?
Thanks in advance.
If this is all your classes do, then I dont think u need any other class then Handler. Just simply let the Handler handle all the flags. It will be easy and simple like that. I think you might be overthinking this. Get a working simple version and then review it and decide if u need to and can refractor it.
I dont know what type your Request_t->flag(x) and Data_t->flag(x) is.
But cant you just do
dbdata_.flagA = request_t.flagA;
dbdata_.flagB = request_t.flagB;
etc. If you can maybe make them an array instead of individual variables, for easier setting.
You may want to consider a policy-based class design. For this, we define both a variadic function template, execute(), and a class template, HandlerHolder, that inherits from Handler and overrides the updateFlags() member function:
template<typename FlagUpdater, typename... FlagUpdaters>
void execute(Data_t& data) {
execute<FlagUpdater>(data);
if constexpr (sizeof...(FlagUpdaters))
execute<FlagUpdaters...>(data);
}
template<typename... FlagUpdaters>
class HandlerHolder final: public Handler {
public:
void updateFlags() override {
if constexpr (sizeof...(FlagUpdaters))
execute<FlagUpdaters...>(dbdata_);
}
};
To this variadic class template, HandlerHolder, you can pass classes (i.e., policies) as template arguments that are callables and set the proper flags. The function call operator (i.e., operator()) of these policy classes are called in its overridden member function updateFlags().
You would then define the policy classes like:
struct AFlagSetter {
void operator()(Data_t& dbdata) const {
dbdata.flagA = 1;
}
};
struct BFlagSetter {
void operator()(Data_t& dbdata) const {
dbdata.flagB = 1;
}
};
struct CFlagSetter {
void operator()(Data_t& dbdata) const {
dbdata.flagC = 1;
}
};
Note that you can also easily define policies for clearing the flags, for example:
struct CFlagClearer {
void operator()(Data_t& dbdata) const {
dbdata.flagC = 0;
}
};
By means of type aliases you can introduce type names for the handlers you were looking for:
using ACHandler = HandlerHolder<AFlagSetter, BFlagSetter>;
using ABCHandler = HandlerHolder<AFlagSetter, BFlagSetter, CFlagSetter>;

Dynamic lists and polymorphism

I have a map of type < lookup_ID, vector< parentclass*>> each location in the map holds a vector of type child class. The idea behind this system is the ability to add a child into its associated map using an add(parentclass*) function and it would be able to find its associated vector of child type. I tried using templates and casting to get the vector to recognized the type of child input into the add function with no luck. I don't want to have to declare an add function for each child of parent, and no matter how I did it I had to declare a function for each type. I could take them out of the map but then again I'm left with the issue of calling each child for any function I want to implement. Is their no way to match types of polymorphic structures into dynamically allocated lists?`
class Piece
{
public:
pieceType ID;
//...
}
class Infantry :
public Piece
{
public:
//...
};
class Artillery :
public Piece
{
public:
//...
};
//...
//In some other classes somewhere
std::map<pieceType, std::vector<Piece*>*> units;
units.emplace(Infantry_, new std::vector<Infantry*>);
units.emplace(Artillery_, new std::vector<Artillery*>);
//...
template<typename T>
std::vector<T*> operator+(std::vector<T*> a, Piece * b) {
a.push_back(static_cast<T*>(b));
return a;
}
add(Piece * piece){
units.at(piece->ID) = units.at(piece->ID) + piece;
}
Also I am aware that this code has some errors, it was more for an example of what i'm trying to say.
You have to use virtual funciton to get the ID for each child class
class Piece
{
public:
virtual PieceType ID() const = 0;
}
class Artillery
{
public:
virtual PieceType ID() const override { /* return your ID for Artillery */ }
}
class Infantery
{
public:
virtual PieceType ID() const override { /* return your ID for Infantery */ }
}
There's no relation between std::vector<Piece*> and either of std::vector<Infantry*> or std::vector<Artillery*>, so your map can only contain std::vector<Piece*>s.
This is for good reason. Imagine you have a std::vector<Infantry*>, and put a pointer to it into your std::map<pieceType, std::vector<Piece*>*>. You could then insert an Artillery * into that through the map.
Rather than exposing the std::vector<Piece*> directly, you could expose a (read only) view of it that casts to the particular subtype.
Using the ranges library
auto asInfantry = ranges::view::transform([](Piece * p){ return static_cast<Infantry *>(p); });
auto asArtillery = ranges::view::transform([](Piece * p){ return static_cast<Artillery *>(p); });
class PieceMap
{
std::map<pieceType, std::vector<Piece*>> units;
public:
auto Infantry() { return units.at(Infantry_) | asInfantry; }
auto Artillery() { return units.at(Artillery_) | asArtillery; }
};

c++ architecture: callback to generic object member function

This question is based upon: Calling C++ class methods via a function pointer
What i would like to do is to register a generic object member function to a module lower in the architecture, that can invoke an event callback.
What i need is being able to register any object type (generic), so i do not have to have a registration function for each type of object.
Example from 1:
typedef void(Dog::*BarkFunction)(void);
Then to invoke the method, you use the ->* operator:
(pDog->*pBark)();
Example in my code:
// application layer
class ObjectInHighterLayer
{
ObjectInHighterLayer()
{
xyz::registerEventhandler(this, eventCallback); // ??? how to register here ???
}
void eventCallback(int x)
{
}
}
// middleware layer or hal layer
static clientcallback clientCb = NULL;
namespace xyz {
typedef void (GENERIC_OBJECT_TYPE::*clientcallback)(int /*x*/); // ??? how to define callback type here ???
void registerEventhandler(clientcallback cb);
{
clientCb = cb;
}
void task()
{
// ... if event happend
callClients();
}
void callClients()
{
if(clientCb != NULL)
{
clientCb(3);
}
}
}
There are two patterns I am aware of...
virtual
All the callback functions share a class hierarchy, so a single virtual function can be used to dispatch to the correct type.
class CallbackBase {
public:
virtual void anEvent(int myEvent) = 0;
};
This can be registered by a class directly.
class ObjectInHighterLayer
{
ObjectInHighterLayer()
{
xyz::registerEventhandler(this, eventCallback); // ??? how to register here ???
}
void anEvent(int myEvent)
{
// receive callback
}
}
Or indirectly (probably better to use std::function)
class Test {
public:
void callable(int ) {
}
};
typedef void (Test::*Callable)(int);
This can then be called by a proxy object, separating the hierarchy of the callbacks from that of the called.
class MyFunction {
public:
Callable m_f;
Test * m_Test;
MyFunction( Test * pTest, Callable fn) : m_Test(pTest), m_f( fn )
{
}
void anEvent( int x ) {
(m_Test->*m_f)(x);
}
};
Allowing different functions of test to be registered for different callbacks.
static callback
Change the callback mechanism to take an opaque type. This is easier to code, although sacrifices type-safety.
class Callbackable {
static void callback1( void * pThis, int param )
{
Callbackable *_this = static_cast<Callbackable*>( pThis );
_this->callFunction( param );
}
}
The callback1 because it is static shares a function type with similar functions in different classes (outside of any hierarchy). The idea that it is called with an incorrect pThis is the type safety weakness.

Polymorphic Callback Implementation

I am using Component Based Architecture in my application. I'm at the stage where I need to allow a Component to specify a callback that will be executed upon an event.
typedef void(Component::*EventCallback) ();
typedef std::pair<Component*, EventCallback> EventDelegate;
The problem with the above type definition is that all components inherit from Component but will never be a direct Component. So the following line of code is not valid:
MoveComponent* mc = new MoveComponent(); // inherits from Component
EventDelegate ed(mc , &MoveComponent::moveToXY); // Compiler error here: expects Component* not MoveComponent*, and same for EventCallback.
Any ideas how I can achieve a 'Polymorphic' callback? Or any other design/implementation advice?
Example usage:
typedef void(Component::*EventCallback) ();
typedef std::pair<Component*, EventCallback> EventDelegate;
class Component {
// ...
};
class MoveComponent : public Component {
public:
MoveComponent() {
EventDelegate ed(this, &MoveComponent::moveToXY);
ComponentManager::registerEvent(ed);
}
void moveToXY() { }
};
class ComponentManager {
public:
static void registerEvent(EventDelegate ed) {
evtRegistry.push_back(ed);
}
static void runEvent(EventDelegate ed) {
for (int i=0; i<evtRegistry.size(); i++) {
Component* context = evtRegistry.at(i).first;
EventCallback ec = evtRegistry.at(i).second;
context->*ec();
}
}
private:
static std::vector <EventDelegate> evtRegistry;
};
using EventDeligate = std::function<void()>;
auto cp = std::make_shared<MoveComponent>();
auto ed = EventDeligate([cp](){ cp.moveToXY(); });
To do it your way, Component must have a (possibly pure) virtual function moveToXY.