I have this code for a basic entity system I'm testing
Enity.h
class Enemy
{
public:
void attack(Player player);
virtual void die();
protected: //Info variables
int attackDamage;
std::string name;
bool alive;
}
class ChildEnemy1 : public Enemy
{
name = "Enemy1" //Invalid
};
class ChildEnemy2 : public Enemy
{
name = "Enemy2" // Invalid
};
How would you change the Info variables (attackDamage, name, alive) without inheriting a public setter function
(retain encapsulation).
EDIT: This is not a duplicate question as I have not found an adequate answer to this problem on SO
Initialize the members in the constructor.
class ChildEnemy1 : public Enemy
{
ChildEnemy1() : name("Enemy1") {}
};
Related
I have :
class Game
{
};
class Zombie :public Game
{
public:
virtual int getHP() const=0;
};
class Zombiesmall : public Zombie
{
int HPy=30;
public:
int getHP() const;
};
class Zombiebig : public Zombie
{
int HPz=20;
public:
int getHP() const;
};
class Player : public Game
{
int hpk=100;
public:
int getHPK() const;
};
class Barrel: public Game
{
};
My lecturer said, that, there is no sense to functions getHP and getHPK exist at once, so he asked me to change it and he proposed to make one function in Game class, so I presumed that he want me to do virtual function in class Game. I did so, but my question is if there is a sense to do so if I don't need this function in class Barrel at all, but by making virtual function makes me to write the a definition in Barrel anyway and I won't ever use it.
Here's an inheritance tree that should help:
Entity (renamed your Game)
<- Creature (with getHP())
<- Player (one of the implementations)
<- Zombie
<- SmallZombie
<- BigZombie
<- Barrel (without getHP())
In C++:
class Entity { // base for other classes
public:
virtual ~Entity() = default;
};
class Creature : public Entity { // has getHP()
public:
virtual int getHP() const = 0;
};
class Player : public Creature { // is-a Creature => must implement getHP()
private:
int hp = 100;
public:
int getHP() const override {
return hp;
}
};
// similar for zombies
class Barrel : public Entity { // not a Creature => doesn't have getHP()
};
I'm working on a game and I want to make a base Actor class that holds Stat values that are shared among a variety of Actor types, but I'm having an issue understanding how I can accomplish this without having the base class having a different Stats variable than the actor types...
This is exactly what I have made right now (as shown in the code)... However, I want to somehow make the BaseActor "stats" type become either a PlayerStats or a MonsterStats object when it is created...This way the PlayerActor and MonsterActor no longer need the different "monster_stats" and "player_stats" objects as they inherit the correct type from BaseActor. Is this possible? I'm thinking it can be done through templates, but I'm not too versed in those.
class BaseStats {
public:
int defense;
private:
};
class MonsterStats : public BaseStats {
public:
int drop_rate;
private:
};
class PlayerStats : public BaseStats {
public:
int attack_power;
private:
};
class BaseActor {
public:
BaseStats stats;
private:
};
class MonsterActor : public BaseActor {
public:
MonsterStats monster_stats;
private:
};
class PlayerActor : public BaseActor {
public:
PlayerStats player_stats;
private:
};
Have PlayerStats and MonsterStats derive from BaseStats. Have the constructor of each derived BaseActor allocate the stats with:
MonsterActor::MonsterActor()
{
m_stats = make_shared<MonsterStats>();
}
and have
std::shared_ptr<BaseStats> m_stats;
in the base class.
Look for Jeffrey's answer for a better way. But since you wanted to do this through templates (which is not recommended): -
template <typename T>
class BaseActor {
public:
T stats;
};
class MonsterActor : public BaseActor<MonsterStatus> {
public:
};
class PlayerActor : public BaseActor<PlayerStatus> {
public:
};
I have the following Base Class.
class Furniture
{
public:
virtual void Collapse() = 0;
};
With derived classes:
class Table : public Furniture
{
public:
void Collapse()
{
Save(my_file);
}
protected:
void Save(char* filepath);
private:
char* my_file;
};
class Armoire : public Furniture
{
public:
void Collapse()
{
Save(my_file);
}
protected:
void Save(char* filepath);
private:
char* my_file;
};
class Chair : public Furniture
{
public:
void Collapse()
{
Save(); // note - no filepath
}
protected:
void Save();
};
After reading the comments, I have edited this question somewhat, to describe more accurately the problem in hand.
My problem is that all but one of the classes derived from Furniture define the Save() function with a parameter, like Table and Armoire are doing. It's only the Chair class that defines a Save() function with no parameter.
I want to somehow move the declaration of the Save() function - to be part of an interface, and have the derived classes provide the implementation. But that one class Chair that does not require a parameter means that I can't do this.
What is the best way to design this?
Use a default parameter in the base class:
virtual void Collapse( int seconds = 0 ) = 0;
#include <iostream>
class EquationOfMotion
{
public:
// other attributes
virtual void findNextTimeStep() = 0;
};
class SystemModel
{
public:
EquationOfMotion* p_eom;
// other atributes
SystemModel(EquationOfMotion* new_p_eom)
{
p_eom = new_p_eom;
}
};
class VehicleEquationOfMotion: public EquationOfMotion
{
public:
VehicleEquationOfMotion(...){/* initialise attribute*/}
virtual void findNextTimeStep(){}
};
class Vehicle: public SystemModel
{
// ???? Implementation ?????
}
Vehicle is a specialization of SystemModel where p_eom points to VehicleEquationOfMotion.
I would like to initialise, an instance of VehicleEquationOfMotion and point to it p_eom in Vehicle. I want it to be defined only within the scope of Vehicle, and at the same time, not to use heap.
Is it even possible to reside VehicleEquationOfMotion object inside Vehicle without using the heap? (If not, please suggest where the design has gone wrong).
Might be helpful: I thought about the implementation in this question but ran into trouble (see the question).
If I got your question correctly, then do it like this:
class FooChild : public FooParent
{
public:
FooChild (int pX):m_BarChild(pX), FooParent(&m_BarChild) // point p_barPar to instance of BarChild (i.e. m_BarChild)
{
}
private:
BarChild m_BarChild; // instance of BarChild resided in the stack(not the heap) and is local to FooChild
}
If you want to have FooParent.p_barPar to be pointing to a BarChild that resides inside FooChild, you might need to add a default ctor to FooParent and a method as follows as well: set_p_barPar(BarChild* new_p_bar){p_barPar = new_p_bar;}. So you get:
class FooParent
{
public:
BarParent* p_barPar;
FooParent (){}
FooParent (BarChild* new_p_bar)
{
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
protected:
set_p_barPar(BarChild* new_p_bar)
{
p_barPar = new_p_bar;
}
}
Then you can implement FooChild:
class FooChild : public FooParent
{
public:
FooChild(int new_x, BarChild* new_p_bar):_bar_child(new_x)
{
set_p_barPar(&_bar_child);
}
private: //? Depends on your plans
BarChild _bar_child();
}
Use a class template.
class EquationOfMotion { ... };
template <typename EOM>
class SystemDynamics
{
EOM EquationOfMotion;
...
};
class VehicleEquationOfMotion : public EquationOfMotion { ... };
class Vehicle : public SystemDynamics<VehicleEquationOfMotion> { ... };
May be this is what you want. But the design is not safe. You are passing the pointer to a uninitialized object.
class Vehicle: public SystemModel
{
public:
Vehicle(): SystemModel(&_vem)
{
}
VehicleEquationOfMotion _vem;
}
However, it is safer to do the following:
class SystemModel
{
public:
EquationOfMotion* p_eom;
// other atributes
SystemModel()
{
}
};
class Vehicle: public SystemModel
{
public:
Vehicle(): SystemModel(&_vem)
{
p_eom = &_vem;
}
VehicleEquationOfMotion _vem;
};
My question might not be too correct... What I mean is:
class MyClass
{
public:
MyClass()
{
}
virtual void Event()
{
}
};
class FirstClass : public MyClass
{
string a; // I'm not even sure where to declare this...
public:
FirstClass()
{
}
virtual void Event()
{
a = "Hello"; // This is the variable that I wish to pass to the other class.
}
};
class SecondClass : public MyClass
{
public:
SecondClass()
{
}
virtual void Event()
{
if (a == "Hello")
cout << "This is what I wanted.";
}
};
I hope that this makes at least a little sense...
Edit: _This changed to a.
What you need to do is make SecondClass inherit from FirstClass and declare _This as protected.
class FirstClass : public MyClass
{
protected:
string _This;
public:
and
class SecondClass : public FirstClass
What you got doesn't make sense because classes can only see members and functions from their parents (MyClass in your case). Just because two class inherit from the same parent does not mean they have any relation or know anything about each other.
Also, protected means that all classes that inherit from this class will be able to see its members, but nobody else.
I guess that you need something like this (for a sake of simplicity, I've omitted all the unnecessary code):
class Base{
public:
~Base(){}
protected:
static int m_shared;
};
int Base::m_shared = -1;
class A : public Base{
public:
void Event(){
m_shared = 0;
}
};
class B : public Base{
public:
void Event(){
if (m_shared == 0) {
m_shared = 1;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
a.Event();
b.Event();
return 0;
}
To explain above, I'll explain the static data members:
Non-static members are unique per class instance and you can't share them between class instances. On the other side, static members are shared by all instances of the class.
p.s. I suggest that you read this book (especially Observer pattern). Also note that above code is not thread-safe.