Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用虚拟函数而不重写该虚拟函数的目的_C++_Oop_Dynamic_Polymorphism - Fatal编程技术网

C++ 使用虚拟函数而不重写该虚拟函数的目的

C++ 使用虚拟函数而不重写该虚拟函数的目的,c++,oop,dynamic,polymorphism,C++,Oop,Dynamic,Polymorphism,我目前正在学习教育课程,探索编码面试。虽然这是一门非常好的课程,并且很好地解释了算法,但它并不总是解释代码 有几次我看到了virtual函数作为动态函数的使用(很清楚,我指的是需要实例化对象才能调用的函数)。通过阅读virtual函数,我发现它们被用来实现一些面向对象的原则,比如运行时多态性,或者只是提高一些代码的可维护性。对于这些算法问题,这似乎完全没有必要。事实上,我只需删除virtual关键字,代码就可以正常运行 我的问题是:为什么作者会使用virtual来定义这些函数 以下是本课程作者使

我目前正在学习教育课程,探索编码面试。虽然这是一门非常好的课程,并且很好地解释了算法,但它并不总是解释代码

有几次我看到了
virtual
函数作为动态函数的使用(很清楚,我指的是需要实例化对象才能调用的函数)。通过阅读
virtual
函数,我发现它们被用来实现一些面向对象的原则,比如运行时多态性,或者只是提高一些代码的可维护性。对于这些算法问题,这似乎完全没有必要。事实上,我只需删除
virtual
关键字,代码就可以正常运行

我的问题是:为什么作者会使用
virtual
来定义这些函数

以下是本课程作者使用虚拟函数的示例:

using namespace std;

#include <iostream>
#include <queue>
#include <vector>

class MedianOfAStream {
 public:
  priority_queue<int> maxHeap;                             // containing first half of numbers
  priority_queue<int, vector<int>, greater<int>> minHeap;  // containing second half of numbers

  virtual void insertNum(int num) {
    if (maxHeap.empty() || maxHeap.top() >= num) {
      maxHeap.push(num);
    } else {
      minHeap.push(num);
    }

    // either both the heaps will have equal number of elements or max-heap will have one
    // more element than the min-heap
    if (maxHeap.size() > minHeap.size() + 1) {
      minHeap.push(maxHeap.top());
      maxHeap.pop();
    } else if (maxHeap.size() < minHeap.size()) {
      maxHeap.push(minHeap.top());
      minHeap.pop();
    }
  }

  virtual double findMedian() {
    if (maxHeap.size() == minHeap.size()) {
      // we have even number of elements, take the average of middle two elements
      return maxHeap.top() / 2.0 + minHeap.top() / 2.0;
    }
    // because max-heap will have one more element than the min-heap
    return maxHeap.top();
  }
};

int main(int argc, char *argv[]) {
  MedianOfAStream medianOfAStream;
  medianOfAStream.insertNum(3);
  medianOfAStream.insertNum(1);
  cout << "The median is: " << medianOfAStream.findMedian() << endl;
  medianOfAStream.insertNum(5);
  cout << "The median is: " << medianOfAStream.findMedian() << endl;
  medianOfAStream.insertNum(4);
  cout << "The median is: " << medianOfAStream.findMedian() << endl;
}
使用名称空间std;
#包括
#包括
#包括
类MedianoFastStream{
公众:
优先级\u队列maxHeap;//包含前半个数字
优先级\u队列minHeap;//包含数字的后半部分
虚拟void insertNum(int num){
if(maxHeap.empty()| | maxHeap.top()>=num){
push(num);
}否则{
minHeap.push(num);
}
//要么两个堆的元素数相等,要么最大堆的元素数相等
//元素多于最小堆
if(maxHeap.size()>minHeap.size()+1){
minHeap.push(maxHeap.top());
maxHeap.pop();
}else if(maxHeap.size()

或者只是提高一些代码的可维护性

没有

对于这些算法问题,这似乎是完全没有必要的。事实上,我可以删除virtual关键字,代码仍然运行

我的问题是:为什么作者可能会使用virtual来定义这些函数

我在这里看到三种可能性:

  • 作者将在后面的章节中继承这个类,现在通过在成员函数声明中添加
    virtual
    “准备就绪”。我个人认为这是一个有点奇怪的选择(特别是他们当时可能还想添加一个虚拟析构函数),但可能会继续阅读并找到答案

  • 作者总是出于习惯这样做,即使他们不需要这样做。有些人喜欢将每个函数都虚拟化,以便“默认”获得动态多态性,而不必在以后从它派生时更改基类。我个人认为这也是一件非常奇怪的事

  • 作者犯了一个错误

  • 动态函数(很清楚,我指的是需要实例化对象才能调用的函数)


    我们称这些非静态成员函数。

    “我的想法是这是C++领域的最佳实践”。这是一种选择。另一种是你看到了一个货物邪教编程的例子。所以,你问的很好。如果你有更大的兴趣去学习习语C++,考虑一下签出。你有一个好的观点。特别是,<代码>虚拟< /> >变得有用(仅)。当您使用继承时,从上面显示的类继承将是一个糟糕的主意(基类应该几乎总是有一个虚拟析构函数)。在编写良好的代码中,这样的
    virtual
    通常被理解为是一个自定义点。也就是说,它是一个有意被编写子类的人潜在覆盖的函数。
    virtual
    显然与继承相关联,既有继承,也有继承(即,如果用户将来可能自定义这些类,即使现在只有一个基类)。您可以将其与纯虚拟(
    =0
    )或某些关键字(如
    final
    )相结合,强制/显示类作为一个整体的特定用法。但是,如果没有人要从类继承(因为它隐藏在你的代码中),我不认为有任何理由使用
    virtual
    @Frank每个非
    private
    成员函数都应该是可继承的,否则你的设计不是OO友好的。
    virtual
    并没有真正增加(或减少)这一点。