无法从类型基类的指针访问派生类方法

时间:2014-05-06 08:24:09

标签: c++ oop vector stl dynamic-programming

我应该说明我对OOP有点新意。  我想要创建一个指向Person的类型指针向量,该向量具有GetName()方法,并从我的Player类中获取派生Person的方法GetSpg()。我收到错误“GetSpg()不是Person的成员”。我的问题是:有没有办法从向量访问这两个函数,以便如果它指向一个Person不显示该方法但是它是否这样做?

这是我的代码:

#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; };

3 个答案:

答案 0 :(得分:4)

你不能。 类型为Person的指针只能用于访问属于Person对象的数据/地址(函数)。编译器根本无法知道可能Person派生的所有类,因此哪些操作是合法的。

看看动态投射。 MSDN Reference | Tutorial

简而言之:

Player* pPlayer = dynamic_cast<Player*>(pPerson);
if (pPlayer) {
  //Use the pointer like a player pointer
  //Note: You can only call player functions from pPlayer, not pPerson
} else {
  //Use the pointer like a person pointer
}

请注意,此转换是一个运行时操作。在编译时,编译器会看到您使用Player指针访问Player代码,很高兴允许这样做!

免责声明:我发现您的代码难以理解,因此请在文本中将此问题作为答案

答案 1 :(得分:2)

您遇到的问题与classic animal/cat/dog example非常相似。基本的想法是你有一个基类 - 动物 - 和两个派生自它的类 - 猫和狗。

class Animal {
    public:
    Animal() {}
    virtual ~Animal() {}
};

class Dog : public Animal {
    public:
    Dog() : Animal() {}

    void bark() { std::cout << "Woof" << std::endl; }

    ~Dog() {}
}

class Cat : public Animal() {
    public:
    Cat() : Animal() {}

    void meow() { std::cout << "Meow" << std::endl; }

    ~Cat() {}
}

现在,如果您声明一个Cat或Dog对象,很明显您可以调用bark()或meow();但如果你声明一个Animal对象,就无法知道它是猫还是狗,所以你不能调用这两种方法。

在您的情况下,您将Person作为基类,将Player作为派生类。您可以进一步派生Person并拥有一个新类NonPlayer,这样Person将扮演与Animal相同的角色,而Player和NonPlayer将分别扮演Cat和Dog。

如果确实需要从指向Person对象的指针访问Player方法,则需要先将Person *转换为Player *。但是,您需要确保之前内部的指针是Player *。如果不是,您很可能会收到编译错误。

答案 2 :(得分:0)

有关向上和向下转换的概念,这些概念对于理解您的问题至关重要。你可以使用dynimc_cast的概念,这个Link将有助于理解。