Pointers disappear after calling sub-routine of child class - c++

I am trying to do One class with some features that will be em common with other (Inheritance). This is my principal class:
class SREngineJulius_father {
protected:
bool g2pInit;
Recog *recog;
Jconf *jconf;
public:
bool InitG2P(std::string dic, std::string model, int pos_process_flag=-1);
bool Init_AM(std::string configStr);
};
The two function InitG2P and Init_AM, will make updates in recog and jconf. This updates is something that all child objects of the child class must have.
class SREngineJulius: public SREngineJulius_father
{
DFA_INFO *dfaInfo;
WORD_INFO *wordInfo;
WORD_INFO *wordInfo_init;
Output lastResult;
TListString lastCmdList;
bool startNotifyCallbackLoop;
bool terminate;
bool pause;
DFA_INFO* copy_dfa_info(DFA_INFO* dfa);
DFA_INFO* create_commands_dfa_info();
static void status_recready(Recog *recog, void *dummy);
static void status_recstart(Recog *recog, void *dummy);
static void output_result(Recog *recog, void *dummy);
static void put_hypo_phoneme(WORD_ID *seq, int n, WORD_INFO *winfo);
std::string ReplaceSpace(std::string &str);
std::string RestoreSpace(std::string &str);
public:
bool InitG2P(std::string dic, std::string model, int pos_process_flag=-1);
char* NotifyCallbackLoop(char *ficheiro_wav);//AXY5
int SREngineJulius::Audio_Buffering(char* buffer_audio, int sizefile, int end_flag_, int flag_alocation);//AXY5
void Callbacks();
public:
~SREngineJulius();
bool InitSREngine(std::string recoConfig);
bool DynamicAddCommands(TListString &cmdlist, int startRecog = -1);
bool DynamicAddCommands(std::string cmdlist, std::string sep=" ", int startRecog = -1);
void Release();
};
So the problem is, when I call a routine of the child class, recog and jconf are deleted.

You should make functions in your class that edify the two variables. Try inserting those into a anonymous struct. That way they're easily accessible.
Remember:
. =reference
-> =pointer
Lastly, you are changing recog in a couple of those function declarations.
Try to make sure that the functions are friendly in the functions you make. If they are not, you won' be able to use them.
P.s. children of child classes, these need accessor functions. They have to change the pointers through upward inheritance. So you would want to have the child class of the grandparent have a class that changes it's pointers. You would do that by having a function which accesses the child, in the grandchild. That way you're receding back into the function. That's how it's related.

Related

C++ class templates: different data members and member functions for different typenames

I have two classes that intend to function the same but with different data members, as such:
class Character
{
protected:
string job;
int MAX_HP;
int HP;
int STR;
int DEX;
int INT;
public:
Character();
Character(string job,
int max_hp,
int str=0, int dex=0, int inte=0);
string get_name();
// get func and set func
int get_MAX_HP();
void add_MAX_HP(int MAX_HP);
int get_HP();
void add_HP(int HP);
int get_STR();
void add_STR(int STR);
int get_DEX();
void add_DEX(int DEX);
int get_INT();
void add_INT(int INT);
}
class Monster
{
protected:
string name;
int MAX_HP;
int HP;
int ATK;
int DEF;
public:
Monster(string name, int MAX_HP, int Shield, int Barrier, int ATK, int DEF);
string get_name();
int get_MAX_HP();
void add_MAX_HP(int MAX_HP);
int get_HP();
void add_HP(int HP);
int get_ATK();
void add_ATK(int ATK);
int get_DEF();
void add_DEF(int DEF);
}
These are all the difference between the two classes I have designed so far. As I am writing the other functionalities I start to realize that they work essentially the same despite the different data members, along with their getter and setter. I feel like making the two class declarations code into one. I think I can write a virtual base class for sure, that contains the union of all data members and member functions, and only initialize some members for Character or Monster. But can I achieve it with template? With template Character and Monster are instantiation of one template, but I am uncertain whether can template initialize different members in response to different typename...
Edit:
Allow me to be more specific. The Character and Monster are designed to fight. It also allows the Character and Character, Monster and Monster to fight. With two classes, there will be four member function in total to design:
class Character{
void Fight(Character hero, Monster enemy);
void Fight(Character hero, Character enemy);
}
class Monster{
void Fight(Monster mon, Character enemy);
void Fight(Monster mon, Monster enemy);
}
I want to make the Fight() function spread among two classes into one block to save code, as they all share using ATK/STR/DEX/INT to deduct HP of other object, DEF deducted for Monster. In finishing writing the function, I suspect a lot of copy & paste would be done, and code is already lengthy for getter and setter with similar functionalities, for each data member. I noticed a partial specialization for template. But it would be the same to write two separate code blocks for Character and Monster. Is it my class design that impedes merging homogeneous codes, or is it inevitable for C++, to write class with slight difference?

how to create a class from an identifier?

the title might be a bit misleading, but I want to give some instance of a class an instance of a different class through polymorphism. I think that may have been even more misleading so I'll give an example;
Say I have a class called Spell, that is a parent class to the class Firebolt. I want another class, say Character, to be able to have the spell, 'Firebolt', in an its memory without ever having to #include the files for 'Firebolt'.
Now, I can think of a way that prior games have done this before. By giving each spell (or whatever else specific class type) a static const string ID or name and in spell having some function that can access this ID/name and return a new Firebolt() if they are the same.
This sounds pretty good actually, the problem I'm having is I don't know how to code this. I'm not sure how I can access these ID's from the parent class, and I'm not sure how to make a virtual function that will actually return the correct Spell. Any help would be amazing. I'll also provide the actual class code I'm working with here in case it might help you guys to answer, or someone with a similar problem to solve it.
The parent class;
class Art {
std::string name;
int EPCost;
int castTime;
int AoESize;
public:
Art(std::string n, int cp, int ct, int as):name(n), EPCost(cp), castTime(ct), AoESize(as) {}
virtual ~Art() {}
static Art* findArt(std::string ID);
int getAoESize() {return AoESize;}
std::string getName() {return name;}
int getEPCost() {return EPCost;}
virtual int getBaseDamage() = 0;
};
The subclass;
class FireBolt:public Art {
static const std::string name;
static const int EPCost;
static const int castTime;
static const int AoESize;
static const std::string ID;
public:
FireBolt():Art(name, EPCost, castTime, AoESize) {}
~FireBolt() {}
int getBaseDamage();
};
All you need to do is make your FireBolt::ID public.
class FireBolt:public Art {
public:
static const std::string ID;
...
};
Art* Art::findArt(const std::string& ID)
{
if (ID == FireBolt::ID)
return new FireBolt(...);
...
}

graphic drawing class organisation

I have a basic 4x20 character LCD that I would like to use for displaying a menu with buttons using an Arduino as the driver (limited standard library support).
Example LCD menu and buttons
I'm thinking of producing an interface class GraphicObject that all graphical objects then inherit from (such as Button, MenuItem etc.). It seems logical that the GraphicObject class should have a draw method which can be overridden.
At the moment, I have a class called Lcd which covers the low level drawing of text and character positioning. In order to draw anything, I will need access to one of these Lcd objects. If I include a pointer to the Lcd object within my GraphicObject or derived objects, I couple them and make them Lcd only objects. If I change the type of display device these classes aren't suitable any more.
How can the classes be organised to keep them loosely coupled and allow for a change in display types at a later date? Should I have LCDButton LCDMenuItem which then inherit from a Button and MenuItem interface, then create additional objects for the other display device (OtherDisplayButton OtherDisplayMenuItem)?
Any suggested reading? I've looked at many examples, but none of them seem to go into details about the function of a draw method and whether the device should be accessed directly or through another controlling object.
Thanks
Edit 1
Brief code idea overview
#include "Arduino.h"
class Lcd {
public:
struct Parameters {
uint_fast8_t numberLines;
uint_fast8_t numberCharacters;
// uint_fast8_t* lineOffsets;
Print* serial; // Can be any Serial device (all inherit from Print).
};
protected:
Parameters parameters_;
const uint_fast8_t escapeCode_ = 0x1B;
const uint_fast8_t directCode_ = 0xFE;
void sendCommand_(uint_fast8_t command, uint_fast8_t parameter = 0);
void sendCommandDirect_(uint_fast8_t command);
public:
Lcd(Parameters parameters);
void clearDisplay(void);
void moveCursor(uint_fast8_t line, uint_fast8_t character);
void resetDisplay(void);
void customCharacter(const uint_fast8_t address,
const uint_fast8_t characterMap[8]);
void write(uint8_t character);
// Boilerplate print forwarders.
void print(const char character);
void print(const String &string);
void print(const char string[]);
// Boilerplate println forwarders.
void println(const char character);
void println(const String &string);
void println(const char string[]);
void println(void);
};
class GraphicObject {
virtual void draw(void)=0;
};
class Button: public GraphicObject {
public:
typedef void (*buttonAction)(void);
virtual void setText(const String text)=0;
virtual const String getText() =0;
virtual bool isActive()=0;
virtual void setActive(bool)=0;
virtual void setAction(buttonAction action)=0;
};
class MenuItem: public Button {
public:
typedef void (*menuAction)(void);
virtual MenuItem* parentItem()=0;
virtual const MenuItem* addItem(String text, menuAction action)=0;
};
class VScrollbar: public GraphicObject {
public:
virtual void setAtTop(bool atTop);
virtual void setAtBottom(bool atBottom);
};
class LcdButton: public Button {
private:
Lcd* lcd_;
String text_;bool active_;
public:
LcdButton(Lcd* lcd);
void draw(void);
void setText(String text);
const String getText();bool isActive();
void setActive(bool);
void setAction(Button::buttonAction action);
};
class LcdWindow: public GraphicObject {
private:
LcdButton* lcdButtons_ = nullptr;
public:
enum class Position
: uint_fast8_t {
LEFT,
RIGHT
};
bool addButton(LcdButton* lcdButton, uint_fast8_t line, uint_fast8_t offset);
bool addVScrollbar(VScrollbar* vScrollbar, Position position);
void draw();
};
int main(void) {
Lcd::Parameters lcdParameters;
lcdParameters.numberCharacters = 20;
lcdParameters.numberLines = 4;
lcdParameters.serial = &Serial1;
Lcd lcd = Lcd(lcdParameters);
LcdButton myButton(&lcd);
myButton.setText("Select");
myButton.setActive(true);
LcdWindow lcdWindow;
lcdWindow.addButton(&myButton, 1, 1);
lcdWindow.draw();
while (1){}
return 0;
}
There are different ways to do this. In principle, you should define an interface (API) to your low-level LCD driver module(s) and call only functions of your low level api to draw something. The implementations of this api can then exchanged without the need to change the high level code.
The simplest way to do this is to define an abstract c++ base class where all lcd driver implementations have to be derived from. The base class should have virtual methods that need to be overloaded by the derived implementations.
But a litte information: virtual methods in c++ classes requires the compiler to generate a method pointer table for every object that is created when the object is instantiated; this needs some more memory. Also, all function calls to objects of these classes are indirect (the compiler generates code that first lookup the real function pointer and then calls the function using this pointer), which makes the resulting code slightly slower.

Gather data from loosely coupled classes

In a software project, I've done my best to make the classes loosely coupled. Now I'm struggling to get the scattered data (from objects of the loosely coupled classes) into a data object. This data object (e.g. for logging) is predefined and has to be filled with data from objects of several classes.
As the real code is proprietary, I've written the code below which should illustrate my problem:
class Gear {
public:
Gear(unsigned int amount);
~Gear();
void shiftUp();
void shiftDown();
private:
const unsigned int amount;
unsigned int current;
};
class Speedometer {
public:
Speedometer();
~Speedometer();
void display() const;
private:
double currentSpeed;
};
class Bike {
public:
Bike(unsigned int nrWheels, Gear& gear, Speedometer& speedometer);
~Bike();
void peddle() const;
void break() const;
private:
const unsigned int nrWheels;
Gear& gear
Speedometer& speedometer;
};
class Cyclist {
public:
Cyclist(const std::string name, Bike& bike);
~Cyclist();
void ride();
private:
const std::string name;
Bike& bike;
};
class Factory {
public:
Factory();
~Factory();
Cyclist& build() const;
};
struct PredefinedData {
PredefinedData();
~PredefinedData();
std::string cyclistName;
unsigned int nrWheels;
unsigned int currentGear;
double currentSpeed;
};
A Factory (object) builds a Cyclist (object) with all objects that it references (recursively). The state of all these objects will change during the execution of the program. In order to e.g. log the state of a Cyclist object with all its references, an object from the PredefinedData class is used. This object has to be filled with data from Cyclist and its references.
Some thoughts/tests of my own:
I've tried giving every class a reference of the PredefinedData object, but that meant that private data of objects would be known by other objects.
I've tried a Filler object that provides functions to fill the PredefinedData object, but it feels like duplicating the PredefinedData class.
I've also considered inheriting a class from several classes to be able to give every class access to just the data it should have access to/fill.
How would you solve this? Is there a design pattern for this situation?
I'd do this:
class Cyclist {
public:
Cyclist(const std::string name, Bike& bike)
: data(name), bike(bike) {}
const PredefinedData& getPredefinedData()
{
data.nrWheels = bike.getNrWheels();
data.currentGear = bike.gear.getCurrent();
data.currentSpeed = bike.speedometer.getSpeed();
return data;
}
private:
PredefinedData data; // includes name, used as a cache
Bike& bike;
};

C++ object of class in class not given public access

I have this setup and how i want to use it in main for example:
struct Player{
private:
float posX1, posX2, posY1, posY2;
int user_id;
public:
Player::Player():posX1(NULL), posY1(NULL), posX2(NULL), posY2(NULL){};
float getPosX1();
float getPosY1();
float getPosX2();
float getPosY2();
int getUserId();
void setUserId(int);
void setPosX1(float);
void setPosY1(float);
void setPosX2(float);
void setPosY2(float);
};
struct Room_Data{
private:
int room_id;
Player player_one, player_two;
bool playerOneAlive, playerTwoAlive;
public:
Room_Data::Room_Data():player_one(), player_two(), playerOneAlive(false), playerTwoAlive(false), room_id(NULL){};
void setRoomId(int);
int getRoomId();
void setPlayerOneDead();
void setPlayerOneAlive();
void setPlayerTwoDead();
void setPlayerTwoAlive();
bool isPlayerOneAlive();
bool isPlayerTwoAlive();
Player getPlayerOne();
Player getPlayerTwo();
};
I'm trying to use the following method in main for example:
main.cpp
const int x=10;
Room_Data data[x];
data[0].getPlayerOne().setPosX1(10.0f);
But it doesnt set posx1 because getPlayerOne() provides only private access of the player_one object but i dont know how to give it public access
By having getPlayerOne return a reference to that private variable.
Player& getPlayerOne();
Then you will be able to perform stuff on the result of calling that function, and that stuff will apply to the actual, original member within your class.
Right now you're operating on a temporary copy, instead, due to returning by value.
Frankly, though, if you're going to allow unabashed access to this private variable, why bother with the getter? Just make the variable public.