<hi*****@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com
I am trying to port a python program into c++ to more learn about
c++... so i am trying to do a MVC design.. so here is my events
class Event {
public:
Event() {}
Event(string text) { this->name = text; }
virtual string getName() { return this->name; }
string name;
};
class PlayerSelEvent : public Event {
public:
PlayerSelEvent() {}
PlayerSelEvent(string text, string player) : Event(text) {
this->player = player; }
virtual string getPlayer() { return this->player; }
string player;
};
now here is how a function gets it
void AppMasterController::Notify(Event *ev) {
std::cout << "got an event: " << ev->name << std::endl;
// checking the type
if (ev->getName() == "Set Player") {
PlayerSelEvent *nameEvent = dynamic_cast<PlayerSelEvent*>(ev);
std::cout << "players name is: " << nameEvent->getPlayer() <<
std::endl;
}
}
no the nameEvent->getPlayer() forces the program to quit due to a run
time error
am I doing it right to access the getPlayer() function?? or do I need
to do something else??
thanks
mike
I don't know for sure what is causing your runtime error. Selected excerpts
from your code are rarely adequate to identify a problem. We are not
psychic. You should supply complete compileable code that exhibits the
problem. Often this will be a simplified version of your original code.
I will make a couple of points. First, dynamic casting is rarely needed in a
well written program. You can generally achieve the same effect in a less
error-prone way using virtual functions. Second, if you are to use dynamic
casting, then you might as well use all the power that it offers. You seem
to be duplicating its operation.
Judging by your code excerpt, you have a function that takes a base class
(Event) pointer as an argument. If the pointer actually points to a base
class object, you want the function to output only the name member from the
base class. If it points to a derived class (PlayerSelEvent) object, you
want the function to output both the name member from the base class and the
player member from the derived class.
The simplest way to do this is with a virtual function, Display, defined as:
virtual void Display()
{
std::cout << "got an event: " << getName() << std::endl;
}
in Event and
virtual void Display()
{
Event::Display();
std::cout << "players name is: " << getPlayer() << std::endl;
}
in PlayerSelEvent. Your Notify function is then simply:
void AppMasterController::Notify(Event *ev)
{
ev->Display();
}
Incidentally, pev is a much better name for a pointer to an Event than is
ev.
If this approach is not possible and you must use dynamic casting, then the
appropriate function definition is as follows:
void AppMasterController::Notify(Event *ev)
{
std::cout << "got an event: " << ev->name << std::endl;
PlayerSelEvent *nameEvent = dynamic_cast<PlayerSelEvent*>(ev);
if (nameEvent)
{
std::cout << "players name is: " << nameEvent->getPlayer() <<
std::endl;
}
}
The point here is that the result of dynamic casting will tell you what is
being pointed to. If it is a PlayerSelEvent object, then the casting works
and you get the address of the object. If it is an Event object, then the
casting fails and nameEvent will be zero, indicating that you should not
attempt to call nameEvent->getPlayer() (doing so will likely cause a runtime
error). Incidentally, nameEvent would be better called pnameEvent.
You seem to be attempting to test what is pointed to yourself by testing for
a name of "Set Player". If a base class object has this name, then your if()
condition succeeds, nameEvent becomes zero as a result of the dynamic cast,
and nameEvent->getPlayer() is then an error.
--
John Carson