Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

why it outputs "says hi to" when those two interact object are not in same object type?

0 votes
asked May 27, 2023 by Rez (120 points)
#include <iostream>

#include <string>

#include <typeinfo>

using namespace std;

class Object{

    protected:

        string name;

        int dmg;

public:

    Object(){

        name = "Object";

            dmg = 0;

    }

    Object(int x){

        name = "Object";

            dmg = x;

    }

    Object(string n, int x){

        name = n;

            dmg = x;

    }

void Action(){

cout<<"Do nothing......"<<endl;

}

void MoveTo(int x, int y){

            cout<<"Walking to location("<<x<<","<<y<<")"<<endl;

}

void Attack(int dmg){

            cout<<"Attack......."<<endl;

            cout<<"Damage: "<<dmg<<endl;

}

string Whoami(){

            return name;

}

void InteractWith(Object& obj) {

        if (typeid(*this) == typeid(obj)) {

            cout << name << " says Hi to " << obj.Whoami() << endl;

        }

else {

            cout << name << " attacks " << obj.Whoami() << endl;

        }

    }

};

class Player: public Object{

    private:

        int magicDmg;

    public:

        Player():Object("Player",10){

            magicDmg = 10;

            //cout<<"dmg = "<<dmg<<endl;

            //cout<<"magicDmg = "<<magicDmg<<endl;

        }

        Player(string myName):Object(myName,10){

            magicDmg = 10;

            //cout<<"dmg = "<<dmg<<endl;

            //cout<<"magicDmg = "<<magicDmg<<endl;

        }

    void Action(){

MoveTo(10,20);

Attack();

}

void Attack(){

            cout<<"Casting magic......"<<endl;

            Object::Attack(dmg+magicDmg);

}

};

class Monster: public Object{

    public:

        Monster():Object("Monster",20){

            //cout<<"dmg = "<<dmg<<endl;

        }

        Monster(string myName):Object(myName,20){

            //cout<<"dmg = "<<dmg<<endl;

        }

    void MoveTo(int x, int y){

            cout<<"Flying to location("<<x<<","<<y<<")"<<endl;

}

void Action(){

MoveTo(10,20);

Attack(dmg);

}

};

int main(){

    Player john("John"), ken("Ken");

    Monster orc("Orc"), goblin("Goblin");

    cout<<"---------------------------"<<endl;

    john.InteractWith(ken);

    john.InteractWith(orc);

    john.InteractWith(goblin);

    cout<<"---------------------------"<<endl;

    ken.InteractWith(john);

    ken.InteractWith(orc);

    ken.InteractWith(goblin);

    cout<<"---------------------------"<<endl;

    orc.InteractWith(john);

    orc.InteractWith(ken);

    orc.InteractWith(goblin);

    cout<<"---------------------------"<<endl;

    goblin.InteractWith(john);

    goblin.InteractWith(ken);

    goblin.InteractWith(orc);

return 0;

}

1 Answer

0 votes
answered Jun 1, 2023 by Peter Minarik (89,130 points)

Your problem is that when void InteractWith(Object& obj) is called, the typeid of *this and obj are the same: Object.

This is because InteractWith(Object& obj) is a simple function on the class Object. So the type id is evaluated at compile time: Object.

What you want instead is that the type id to be evaluated dynamically at run time based on inheritance. But your function is bound to Object. To allow the detection of dynamic types, make it a virtual function: virtual void InteractWith(Object& obj).

On a side note here: many consider using typeid for bad programming practice as usually what you're using typeid for should be achieved via inheritance and virtual functions. Please, read more on the matter here.

Good luck!

Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...