I should specify that I'm a bit new to OOP. I'm tying to make a vector of type pointer to Person that has a method GetName() and access a method GetSpg() from my Player class that derives Person. I get an error "GetSpg() is not a member of Person". My question would be: is there any way to access both functions from the vector so that if it points to a Person to not show that method but if it is to do so?
Here is my code:
#ifndef _PERSON_H
#define _PERSON_H
#include <iostream>
#include <algorithm>
typedef std::pair<std::string, std::string> StrPair;
class Person :private StrPair
{
public:
Person(const std::string& fn = "none", const std::string& sn = "none") :StrPair(fn,sn){};
virtual void Update(const std::string& fn, const std::string& sn){ StrPair::first = fn; StrPair::second = sn; };
virtual const StrPair& GetName(){ return (const StrPair&)(*this); };
};
#endif
typedef std::pair<int, int> IntPair;
class Jucator: public Person, private IntPair
{
std::string tip;
int spg;
int average;
public:
Jucator(const std::string& fn = "none", const std::string& sn = "none",
const std::string& t = "", const int& _spg = 0, const int& _avr = 0,
const int& _g = 0, const int& _r = 0) :Person(fn, sn),tip(t),spg(_spg),average(_avr),IntPair(_g,_r){};
virtual void Update(const std::string& fn, const std::string& sn, const std::string& t, const int& _spg, const int& _avr,
const int& _g, const int& _r){
Person::Update(fn, sn); tip = t; spg = _spg; average = _avr; IntPair::first = _g; IntPair::second = _r;
};
virtual const int& GetSpg(){ return spg; };
You can't. A pointer of type
Person
can only be used to access data/addresses(functions) that are part of thePerson
object. The compiler simply has no way of knowing what all classes could be deriving fromPerson
and hence which operations are legal.Have a look at Dynamic casting. MSDN Reference | Tutorial
In brief:
Note that this casting is a runtime operation. At compile time, the compiler sees you using the
Player
pointer to accessPlayer
code, which it is happy to allow!Disclaimer: I found your code tough to follow, so consider this an answer to your question in text
The problem you're facing is very similar to the classic animal/cat/dog example. The basic idea is you have a base class - Animal - and two classes that derive from it - Cat and Dog.
Now, if you declare a Cat or a Dog object, it's pretty obvious that you can call either bark() or meow(); but if you declare an Animal object, there's no way of knowing whether it's a Cat or a Dog, so you can't call either method.
In your case, you have Person as the base class and Player as the derived. You may further derive Person and have a new class, NonPlayer, so that Person would play the same role as Animal, and Player and NonPlayer would be Cat and Dog respectively.
If you really need to access Player methods from pointers to Person objects, you need to cast the Person* to Player* before. However, you need to be sure before that the pointer inside is a Player*. If it isn't, you'll most likely get a compilation error.
There are concepts of upcasting and downcasting which are essential to understand your problem. You can use the concept of dynimc_cast, this Link would be helpful to understand.