隐藏/虚函数用法C ++

时间:2012-08-25 20:28:19

标签: c++ class function virtual

这是一个特定的问题,我在很长一段时间内都找不到解决方案。我有这段代码:

#include <iostream>

using namespace std;

class Mammal
{
  public:
  Mammal() {cout << "Mammal Constructor\n";}
  virtual ~Mammal() {cout << "Mammal Destructor\n";}
  virtual void Run() {cout << "Mammal Ran One Space\n";}

  protected:
  int mammalDistance;
};

class Horse : public Mammal
{
    public:
    Horse() {cout << "Horse Constructor\n";}
    ~Horse() {cout << "Horse Destructor\n";}
    void Run() {cout << "Horse Ran One Space\n";}
    void Run(int distance) {horseDistance = distance;
                            cout << "Horse Ran " << horseDistance << " Spaces\n";}

    protected:
    int horseDistance;
};

int main()
{
    Mammal *pHorse = new Horse;
    pHorse->Run(5);
    delete pHorse;
    return 0;
}

现在这个代码可以运行,如果我使用void Run(int horseDistance)并将其移动到Mammal中但是我想知道是否有办法将它保留在马中而不会保持隐藏状态。

编辑:我的意思是如果我接受输入并将其移动到Mammal而不是像目前那样在Horse类中使用它,它会编译并按预期工作。 是的,如果它可以在传递时改变horseDistance的值,我希望它。 编辑:哦,我明白你的意思。我编辑了代码。

4 个答案:

答案 0 :(得分:1)

Mammal *pHorse = new Horse;
pHorse->Run(5);

不起作用,因为Mammal中没有带签名void Run(int)的成员函数。更精确:由于签名不同,Horse类中给出的函数void Run(int)不是Mammal中函数void Run()的覆盖。

您应该考虑将void Run(int)添加到Mammal接口,如果它是一个更多子类将实现的函数。

答案 1 :(得分:1)

您有两种选择。一个是跟踪指针是马的事实:

int main()
{
    Horse *pHorse = new Horse;
    pHorse->Run(5);
    delete pHorse;
    return 0;
}

另一种是在Mammal

中声明虚函数
virtual void Run(int mammalDistance) = 0;

如果马匹是唯一运行特定距离的东西,我会选择#1选项,否则选项#2。

答案 2 :(得分:0)

现在你知道pHorse是一匹马,但对于编译器来说,它是不同的。 唯一的方法是使用动态演员来检查如果pHorse是一匹马然后将其施放到Horse *并施放方法Run(5)。

Horse* pHorse2=dynamic_cast<Horse*>(pHorse);
if(pHorse2!=NULL){
   pHorse2->Run(5);
}else{
   pHorse->Run();
}

答案 3 :(得分:0)

我认为你在这里寻找多态性。您的所有派生Mammals只需实施getDistance()setDistance(),并且还可以实施getAnimal()来提供名称。我认为设计上还有一些改进空间,但是你会以这种方式获得多态性。也许是这样的事情:

#include <iostream>

using namespace std;

class Mammal
{
public:
  Mammal() {cout << "Mammal Constructor\n";}
  virtual ~Mammal() {cout << "Mammal Destructor\n";}
  virtual void Run() {cout << getAnimal() << " Ran " << getDistance() << " Space\n";}
  virtual void Run(int p_distance)
  {setDistance(p_distance);
    cout << getAnimal() << " Ran " << getDistance() << " Spaces\n";}

protected:
  virtual void setDistance(int p_distance) {mammalDistance = p_distance;}
  virtual int getDistance() {return mammalDistance;}
  virtual string getAnimal() {return "Mammal";}
  int mammalDistance;
};

class Horse : public Mammal
{
public:
    Horse() {cout << "Horse Constructor\n";}
    ~Horse() {cout << "Horse Destructor\n";}
protected:
    int horseDistance;
    virtual string getAnimal() {return "Horse";}
};

int main()
{
    Mammal *pHorse = new Horse;
    pHorse->Run(5);
    delete pHorse;
    return 0;
}