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()
};
Related
I'm wondering if the following is possible. I wanted my derived class dA to change func() to be pure virtual so that any classes derived from dA must implement func().
Code similar to below compiles without complaint under MSVC even though ddA does not implement func().
The compiler does complain about the below code (see comments). So my question now becomes: is this a standards-compliant way to achieve what I want?
class A {
public:
virtual void func() { /* Some base implementation. */ }
}
class dA : public A {
public:
void func() override = 0; // Is this valid?
}
class ddA : public dA {
}
Pure virtual function should be declared in parent class. Consider the code below:
'''
class Shape {
public:
Shape(int init_x, int init_y) : x(init_x), y(init_y) {}
virtual void scale(int s) = 0;
virtual void print() = 0;
protected:
int x;
int y;
};
These functions should be implemented in children:
class Rect : public Shape {
public:
Rect(int init_x, int init_y, int w, int h);
virtual void scale(int s) { //implementation }
virtual void print() { //implementation }
private:
int width;
int height;
};
However you don't have to implement virtual functions in subclasses since it had been implemented in super class:
Pure virtual function make your class abstract so you can't use its instances.
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") {}
};
Following is a model example. Suppose I have class Creature that has three coordinates x,y,z. I also have inheritance tree:
class Creature {
int x;
int y;
int z;
};
class Mammal : public Creature {common code for mammals};
class Wolf : public Mammal;
class Bat : public Mammal;
class Birds : public Creature {common code for birds};
class Penguin : public Bird;
class Crow : public Bird;
Some creatures can fly, so they should have following member function (implementation is same for all creatures):
void fly(int height) {z = height;}
So I do the following:
class FlyingMammal : public Mammal {
void fly(int height) {z = height;}
//'z' is also used in some methods of non-flying creatures,
//so it can't be moved to FlyingMammal class.
};
class Wolf : public Mammal;
class Bat : public FlyingMammal;
class FlyingBird : public Bird {
void fly(int height) {z = height;}
};
class Penguin : public Bird;
class Crow : public FlyingBird;
However, I have code duplication in FlyingMammal and FlyingBird. Is there standard pattern to avoid it? I suppose some kind of multiple inheritance might fit here, but don't know how exactly to do it.
Note that additional interface like fly() does not introduce new data members, only new member functions. But it uses member data z of Creature class.
I think Curiously recurring template pattern
would be one way to go ... like so
template <typename TThisClass>
class Flier
{
public:
void fly(int z) { static_cast<TThisClass *>(this)->setZ(z); }
};
class Creature {
private:
int x;
int y;
int z;
public:
void setX(int x) { this->x = x; }
void setY(int y) { this->y = y; }
void setZ(int z) { this->z = z; }
// add setter & getter for x, y, z
};
class Mammal : public Creature { /*common code for mammals*/};
class Wolf : public Mammal { };
class Bat : public Mammal, public Flier<Bat> { };
class Bird : public Creature { /*common code for birds*/ };
class Penguin : public Bird { };
class Crow : public Bird, public Flier<Crow> { };
int main(int, char **) { Crow c; c.fly(1000); };
I have these 2 classes.
class ChessPiece
{
public:
ChessPiece();
virtual bool move() = 0;
};
class Bishop: public ChessPiece
{
public:
Bishop();
bool move();
};
I'm trying to determine the type of a ChessPiece after I created it like this
ChessPiece* foo = new Bishop()
I"m trying to get the type of foo (Bishop) not ChessPiece.
Thank You
Well, there are some ways of doing this, have a look at dynamic casting:
class A
{
public:
virtual void Foo() = 0;
};
class B : public A
{
public:
void Foo() { }
};
void Test()
{
A* bar = new B();
if (B* test = dynamic_cast<B*>(bar))
{
// use test here
}
delete bar;
}
Alternatively you can store an enum in the chess piece class defining the piece id.
One example of a way to solve your problem:
enum PieceType
{
King,
Queen,
Rook,
Bishop,
Knight,
Pawn
};
class ChessPiece
{
public:
ChessPiece();
virtual ~ChessPiece();
virtual bool move() = 0;
virtual PieceType GetType() const = 0;
};
class Bishop : public ChessPiece
{
public:
Bishop();
virtual ~Bishop();
virtual bool move();
virtual PieceType GetType() const { return Bishop; }
};
Then use ChessPiece::GetType() to determine what kind of piece this is.
You can use following code.
ChessPiece obj;
Bishop* pObj = dynamic_cast<Bishop*>(&obj);//Change to Bishop,return NULL if failed.
I want to reconstruct my small 3d-engine, it is very small so i place all files in only one project.
now, i want to reconstruct it with interfaces, so i can disperse different modules to the different projects and build them as a dll.
when i do that, i have met a lot of difficulties in the basic design of framework code.
I want to design a 'Object Hierarchy' of my small engine, it is realized in the previous work. for example:
Object
Component
SceneComponent
StaticMeshComponent/SkelMeshComponent
D3DSkelComponent
...
but they are implement directly.
now, i want to use interface(pure virtual class), i have design the basic interfaces(for test ):
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
class IObject
{
public:
virtual std::string GetName() = 0;
};
class IMesh : public IObject
{
public:
virtual void Draw() = 0;
};
class IStaticMesh : public IMesh
{
public:
virtual void BuildSomeMesh() = 0;
};
class ISkeletalMesh : public IMesh
{
public:
virtual void PlayAnim( const std::string& strAnimName ) = 0;
};
class ID3DSkeletalMesh : public ISkeletalMesh
{
public:
virtual void LoadD3D( const std::string& strD3D ) = 0;
};
it looks like ok, but when i try to implement them, i find that it may be a impossible mission.
first, i can write a template class or normal class for IObject, eg:
template < typename TBase >
class TObject : public TBase
{
public:
virtual std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
based on this TObject, I can implement a CMesh:
class CMesh : public TObject< IMesh >
{
public:
virtual void Draw()
{
cout<<"draw mesh" <<endl;
}
};
IMesh* pMesh = new CMesh(); // ok
IObject* pObj = pMesh; // ok
so far, it works well. but how to implement the CStaticMesh/CSkeletalMesh/CD3DSkeletalMesh?
it maybe like this:
class CStaticMesh : public CMesh, public IStaticMesh
{
public:
};
but i have two IObject base class, so i must change all "public xxx" to "virtual public xxx", it looks bad.
another question is CStaticMesh must implement all virtual member function of IStaticMesh, include:
virtual void Draw() = 0;
virtual void BuildSomeMesh() = 0;
even if there is a Draw in CMesh which is a base call of CStaticMesh.
ok, maybe i need a TMesh:
template < typename TBase >
class TMesh : public TObject< TBase >
{
public:
virtual void Draw()
{
cout<<"draw mesh" <<endl;
}
};
and implement CStaticMesh like this:
class CStaticMesh : public TMesh<IStaticMesh>
{
public:
virtual void BuildSomeMesh()
{
cout<<"Build Some Mesh!"<<endl;
}
};
it looks like ok, but how to implment CD3DSkeletalMesh? make a TSkeletalMesh? ok, it is crazy!!!
i think, this is abime.
which is the mistake in this design? how to change the design idea to avoid this dilemma? do you know a idea which can keep the inheritance hierarchy of those interfaces and implement easily?
if i use many virtual inheritance, is there any performance isuue?
You can solve this, as you mentioned, with virtual inheritance. This will create only one instance of a multiply inherited interface class in the hierarchy.
First the interfaces:
class IObject
{
public:
virtual std::string GetName() = 0;
};
class IMesh : virtual public IObject
{
public:
virtual void Draw() = 0;
};
class IStaticMesh : virtual public IMesh
{
public:
virtual void BuildSomeMesh() = 0;
};
class ISkeletalMesh : virtual public IMesh
{
public:
virtual void PlayAnim( const std::string& strAnimName ) = 0;
};
class ID3DSkeletalMesh : virtual public ISkeletalMesh
{
public:
virtual void LoadD3D( const std::string& strD3D ) = 0;
};
Then the implementations:
class CObject : virtual public IObject
{
public:
std::string GetName()
{
return m_strTest;
}
std::string m_strTest;
};
class CMesh : public CObject, virtual public IMesh
{
public:
void Draw()
{
cout<<"draw mesh" <<endl;
}
};
class CStaticMesh : public CMesh, virtual public IStaticMesh
{
public:
void BuildSomeMesh()
{
cout<<"Build Some Mesh!"<<endl;
}
};
...
For the performance implications of this, look at this question.