tags:

views:

113

answers:

4

I am making a simple console game in C++

I would like to know if I can access members from the 'entPlayer' class while using a pointer that is pointing to the base class ( 'Entity' ):

class Entity {

public:
    void setId(int id) {

        Id = id;

    }

    int getId() { return Id; }

protected:
    int Id;

};

class entPlayer : public Entity {

    string Name;

public:
    entPlayer() {

        Name = "";
        Id = 0;

    }

    void setName(string name) {

        Name = name;

    }

    string getName() { return Name; }

};

Entity *createEntity(string Type) {

    Entity *Ent = NULL;

    if (Type == "player") {

        Ent = new entPlayer;

    }

    return Ent;

}

void main() {

    Entity *ply = createEntity("player");
    ply->setName("Test");
    ply->setId(1);

    cout << ply->getName() << endl;
    cout << ply->getId() << endl;

    delete ply;

}

How would I be able to call ply->setName etc?

OR

If it's not possible that way, what would be a better way?

A: 

Either declare setName as virtual (pure or implement) at parent, or use static_cast to access child thru parent pointer (and you have to be sure that the actual object behind the pointer is of child type).

Time to learn C++. ;-)

I would...

class Entity {

public: void setId(int id) {

    Id = id;

}

int getId() { return Id; }

virtual void setName(string name) {} // learn what "pure" is, now it is implemented

protected: int Id;

};

reinterpret_cast is not always an option and ... read details what it does...

AlexanderVX
+3  A: 

It is possible by using a cast. If you know for a fact that the base class pointer points to an object of the derived class, you can use static_cast:

Entity* e = /* a pointer to an entPlayer object */;
entPlayer* p = static_cast<entPlayer*>(e);
p->setName("Test");

If you don't know for sure, then you need to use dynamic_cast and test the result to see that it is not null. Note that you can only use dynamic_cast if the base class has at least one virtual function. An example:

Entity* e = /* a pointer to some entity */;
entPlayer* p = dynamic_cast<entPlayer*>(e);
if (p)
{
    p->setName("Test");
}

That said, it would be far better to encapsulate your class's functionality using polymorphism (i.e. virtual functions).

Speaking of virtual functions, your class hierarchy as implement has undefined behavior: you can only delete an object of a derived type through a pointer to one of its base classes if the base class as a virtual destructor. So, you need to add a virtual destructor to the base class.

James McNellis
A: 

You can do a dynamic cast:

entPlayer * pPlayer = dynamic_cast<entPlayer *>(pointer_to_base);

This will (if successful) result in a derived pointer.

Otherwise NULL is returned.

George Edison
A: 

I would consider doing something like this:

public:
void setId(int id) 
{

    Id = id;

}

void virtual setName( string name ) = 0; // Virtual Function 
string virtual getName() = 0; // Virtual Function

int getId() { return Id; }

protected:
    int Id;

};

class entPlayer : public Entity {

    string Name;

public:
    entPlayer() {

        Name = "";
        Id = 0;

    }

    void entPlayer::setName(string name) {  // Must define function

        Name = name;
}

string entPlayer::getName() { return Name; } // again must define function here

};
Robb