C++ - Casting a variable of {superclass} to {subclass} [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
As a practice program after learning C++, I am developing a text-based game. I am using object-oriented programming style for handling the worlds/their objects. Here's the necessary information about their definitions:
class Object
{
private:
unsigned int id;
public:
unsigned int getID() const { return id; }
};
class TakeableObject: public Object
{
...
};
class EdibleObject: public TakeableObject
{
private:
float healthEffect;
float staminaEffect;
public:
float getHealthEffect() const { return healthEffect; }
float getStaminaEffect() const { return staminaEffect; }
};
class Player
{
private:
float health;
float stamina;
TakeableObject inventory[256];
public:
eat(const EdibleObject* o)
{
health += o->getHealthEffect();
stamina += o->getStaminaEffect();
}
eat(int id)
{
if (inventory[id] == NULL)
throw "No item with that ID!";
eat((EdibleObject) inventory[id]);
inventory[id] = NULL;
}
};
So my question is - in Player::eat(int), is there a way I can make sure the Object at Player::inventory[id] is an EdibleObject (perhaps through exception handling?)

User dynamic cast to check the object type at runtime.
Or you can use a virtual function with default definition in parent and can update it as per your requirement in derived classes.
Instead of eat((EdibleObject) inventory[id]); use the following
EdibleObject *temp = dynamic_cast<EdibleObject *>( &inventory[id] );
if(temp) { eat(*temp); }
else { /* Handling */ }
Your code suffers Object splicing, make sure to get rid of that first.

Related

Problems with getters and setters in C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a problem with my getters and setters in C++. I implemented a Queue, I also implememented a class Process. My queue saves processes. My class Process has two attributes: "Identifier" and "Time" and also has setters and getters. I set 80 as its Time. The problem then is that I want to modify the time to 50 and it doesn't change. I think that the problem is the Queue, but I don't know where. Heres is my fragment of code
Queue<Process> process;
Process x;
x.setIdentifier("Hi");
x.setTime(80);
process.enqueue(x);
process.getElementFront().setTime(50);
process.print();
Here is my Queue code:
class Queue{
private:
int size;
Node <L> *front;
public:
.
.
.
//front()
L getElementFront() const{
return this->front->getElement();
}
Here is my Node code:
class Node{
private:
L elem;
Node *next;
public:
.
.
.
L getElement() {
return this->elem;
}
This is my Process Class:
class Process{
private:
string identifier;
int time;
public:
Process(){
identifier = "";
time = 0;
}
string getIdentifier(){
return identifier;
}
int getTime(){
return time;
}
void setTime(int time){
this->time = time;
}
void setIdentifier(string identifier){
this->identifier = identifier;
}
friend ostream &operator<<(ostream &o, const Process &p);
};
ostream &operator<<(ostream &o, const Process &p){
o<<"Identifier: "<<p.identifier<<"\n";
o<<"Time:"<<p.time<<"\n";
return o;
}
The output of the first code is: Time = 80. I should be Time = 50, but time wasn't modified.
I believe your function "getElementFront" returns a copy of your element, So your queue will never be affected. You can write a function like "setElementFront(int)" to affect the element directly or something like this.

storing fixed known data in classes (c++) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have this class to store fixed known data. Each object should have its own unique id in such way that, when the user calls Belt belt(1), an object with the correct values of name, perimeter, nOfPoints is created. Is there any better way to define these other parameters without a switch-case? Should I design this in another way? What are the disadvantages of such implementation?
class Belt {
private:
int _id;
std::string _name;
int _perimeter;
int _nOfPoints;
public:
Belt(int id){
_id = id;
switch (id)
{
case 1:
_name = "NEO";
_perimeter = 100;
_nOfPoints = 10;
break;
case 2:
_name = "PED";
_perimeter = 200;
_nOfPoints = 12;
break;
case 3:
_name = "ADT";
_perimeter = 400;
_nOfPoints = 20;
break;
}
}
};
Is there any better way to define these other parameters without a switch-case?
You could use a private static map to hold your prototypes:
class Belt {
private:
static const std:map<int,Belt> prototypes;
int _id;
std::string _name;
int _perimeter;
int _nOfPoints;
Belt(int id, const std::string name, int perimeter, int nOfPoints)
: _id(id), _name(name), _perimeter(perimeter), _nOfPoints(nOfPoints) {}
public:
Belt(int id) {
_id = id;
_name = prototypes[_id]._name;
_perimeter= prototypes[_id]._perimeter;
_nOfPoints= prototypes[_id]._nOfPoints;
// Or simpler instead of the lines above:
// *this = prototypes[id];
}
};
const std:map<int,Belt> Belt::prototypes = {
{ 1 , Belt(1,"NEO",100,10) }
, { 2 , Belt(2,"PED",200,12) }
, { 3 , Belt(3,"ADT",400,20) }
};
Also you might be interested to have a look at the Prototype Design Pattern. That's an alternative technique you can use, and gives you better flexibility.
If you're only going to have a fixed set of values to deal with, I'd suggest making static const instances in Belt. This has the advantage of avoiding any lookup overhead, and dealing with invalid input (e.g., somebody passes INT_MAX to your constructor). For example:
class Belt {
private:
int _id;
std::string _name;
int _perimeter;
int _nOfPoints;
Belt(int id, name, perimeter, nOfPoints)
: _id{id}, _name{std::move(name)}
, _perimeter{perimeter}, _nOfPoints{nOfPoints} { }
public:
static const Belt neo(1, "NEO", 100, 10);
static const Belt ped(2, "PED", 200, 12);
// ...
};
A user can create a local Belt by copying one of the existing objects, and still perform any local manipulations that they need.
int main() {
auto myBelt = Belt::neo;
myBelt.some_member_function();
}

Better design pattern for reading other process memory? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm writing a cheat for an offline game, and have a class called Player which is responsible for getting and setting values in another process. However, my design for this class is very poor because the use of the class Player looks very messy and ugly, very difficult to read, and maintain
// declare variables here to read
if (Player.getthis() && Player.getthat() && Player.getthat() ... and so on)
//do stuff
class Player {
...
public:
...
// either of these calls can fail, so I return TRUE on success and FALSE on failure
BOOL GetHealth(float& health);
BOOL SetHealth(float& health);
...
};
So my question is, what is a better way of doing this?
Also: I don't necessarily need to read every single value of Player in memory, only a few at a time. That is why I don't have a single method such as BOOL UpdatePlayer() which will read everything and update the player
Here is how I would do it:
class Player {
public:
class AccessException : public std::exception {
friend class Player;
public:
virtual const char *what() const noexcept {
return "Error getting property with key " + key;
}
private:
AccessException(const std::string &key)
: key(key)
{}
std::string key;
};
float GetHealth() {
if (is_error) {
throw AccessException("health");
}
return health;
}
float GetPosX() {
if (is_error) {
throw AccessException("posX");
}
return posX;
}
};
void do_stuff() {
try {
float health = player.GetHealth();
float posX = player.GetPosX();
// Use health and posX...
} catch (const AccessException &ex) {
std::cerr << ex.what() << std::endl;
}
}

Pointer to Class Member functions [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to store class member function address, to local data structure(table)
typedef struct
{
unsigned int id;
void (TCLASS::*proc)();
} TSTRUCT;
class TCLASS{
public:
void tfunct();
const TSTRUCT t1 = { 1, &tfunct};
};
Though you didn't write a question, assuming you are facing bunch of compiler errors.
See below :
class TCLASS ; //forward declaration
struct TSTRUCT
{
unsigned int id;
void (TCLASS::*proc)( );
// // Use the TSTRUCT constructor
TSTRUCT(int i, void (TCLASS::*fptr)( ) ): id(i), proc(fptr)
{
}
} ;
class TCLASS{
public:
void tfunct();
TCLASS() : t1(1, &TCLASS::tfunct ) // initialize the const member
//~~~~~~~~~~~^ Use &TCLASS::tfunct instead of &tfunct
{
}
const TSTRUCT t1;
};

How do I prototype/populating an array inside a class?(C++) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to fill an array that's a member of a class with data. Do I have to create a function that populates it, or is there a way that I can just enter the values directly?
class example
{
private:
struct exm {
int everything[3];
};
public:
exm demo;
void output();
void populate();
};
If not would this work?
void example::populate() {
demo.everything[0] = 1;
demo.everything[2] = 1;
//and so on... (could probably use a for loop)
}
Since demo is a public member you can access it directly or you can create a member function to set values.
#include <iostream>
class example
{
private:
struct exm {
int everything[3];
};
public:
exm demo;
void output();
void populate(){
demo.everything[2] = 1;
}
};
int main()
{
example Test;
Test.demo.everything[0] = 5;
Test.populate();
std::cout<< Test.demo.everything[0]; //outputs 5
std::cout<< Test.demo.everything[2]; //outputs 1
return 0;
}
`