【问题标题】:Derived class object override a function of base class in a vector of objects派生类对象覆盖对象向量中的基类函数
【发布时间】:2014-02-02 21:51:01
【问题描述】:

所以当派生类存储在其基类的数组中时,我遇到了调用派生类的覆盖函数的问题。

基类称为 Obstacle,派生类称为 Cliff。 Obstacle有一个虚函数drawToBackground,继承自Obstacle的Cliff也有一个函数drawToBackground,两者都是void。

然后我有一个障碍向量,称为 obstsVec。在这个向量中,我存储了一堆障碍物和一个悬崖。现在说悬崖是向量的第五个元素。当我调用 obstsVec[5].drawToBackground();它从 Obstacle 类而不是悬崖类调用 drawToBackground 函数。

这是 c++ 中的一个功能,还是我只是声明了一些错误?

谢谢

【问题讨论】:

  • 没有代码很难确定,但我认为您需要研究对象切片
  • 如何将Cliff 存储在vector<Obstacle> 中?
  • @Beta 不确定。我从 c# 到 c++,我很确定这在 c# 中是可能的。不过,我猜我在 C++ 中使用它是错误的。

标签: c++ object inheritance vector polymorphism


【解决方案1】:

您只在向量中存储基类,正如@juanchopanza 已经提到的,您已经完成了所谓的对象切片。您需要做的是通过指针多态地存储对象。

std::vector<Obstacle*> myObstacles;
myObstacles.push_back(new Cliff());
myObstacles[0]->drawToBackground();
// Remember to delete when you're done

当然,如果您可以访问 C++11,那么您可以忘记内存管理方面的事情:

std::vector<std::unique_ptr<Obstacle>> myObstacles;
myObstacles.push_back(new Cliff());
for (const auto &obstacle : myObstacles)
{
    obstacle->drawToBackground();
}
// No need to delete anything

【讨论】:

  • 嗯,我对很多高级的东西不是很熟悉,所以这些解决方案对我来说都没有多大意义。 myObstacles[0]->drawToBackground(); 是什么?做?第二个例子对我来说没有任何意义,所以我可能会避免使用这种方法,除非有人可以逐行向我解释。
  • 只是最基本的。我知道它们指向内存中的一个位置,您可以使用 & 运算符或其他东西访问该位置。指针可能是我应该更熟悉的领域。 (我是从 c# 到 c++ 的,所以指针对我来说是全新的)
  • @RyanMartin 我的示例将对象存储为指针,您需要这样做,否则您不能多态地引用它们(即在实例上调用虚拟方法)。
  • 好吧,我想我想使用第二种方法,因为我使用的是 c++ 11。但我不明白 for 循环中发生了什么。你介意解释一下这里发生了什么吗?
  • 它被称为“基于范围的for循环”,是C++11中的一个新特性。它循环遍历myObstacles 的所有内容,然后在每个内容上调用drawToBackground 方法。
【解决方案2】:

您的课程可能类似于:

#include <iostream>
#include <vector>

class Obstacles {
public:
    Obstacles() {};
    virtual void drawToBackground() {
    std::cout << "Obstacle ";
    }
};

class Cliff : public Obstacles {
public:
    Cliff() : Obstacles() {};
    virtual void drawToBackground() {
    std::cout << "Cliff ";
    }
};



int main(int argc, char* argv[]) {
    std::vector<Obstacles*> vec;
    vec.push_back(new Obstacles());
    vec.push_back(new Cliff());
    vec[1]->drawToBackground();
    delete vec[1];
    delete vec[0];
    vec.clear();
}

您在上面提到了数组...确保永远不要多态地使用数组,因为这会导致未定义的行为。

【讨论】:

    猜你喜欢
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多