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
并没有真正增加(或减少)这一点。