具有重写函数的继承 我在看一些C++示例代码,它有效地有以下内容: class Foo : public mynamespace::Bar { public: Foo() { // Do some stuff } void Delta() override { // Do some stuff Bar::Delta(); } };
我很难理解为什么行具有重写函数的继承 我在看一些C++示例代码,它有效地有以下内容: class Foo : public mynamespace::Bar { public: Foo() { // Do some stuff } void Delta() override { // Do some stuff Bar::Delta(); } };,c++,C++,我很难理解为什么行Bar::Delta()存在。假定类Foo继承类Bar,那么当调用Foo::Delta()时,肯定会覆盖Bar::Delta()中存在的任何内容,因此此行是多余的 还是我误解了整个继承权的事情?也许override不会覆盖所有内容 Bar::Delta(); 是一个函数调用。这不就是它看起来的样子吗 它调用的是Delta的基类版本,除了Foo版本所做的任何额外工作之外,它还显式地将其限定为Bar::Delta 也许覆盖并不能覆盖一切 Bar::Delta(); overr
Bar::Delta()代码>存在。假定类Foo
继承类Bar
,那么当调用Foo::Delta()
时,肯定会覆盖Bar::Delta()
中存在的任何内容,因此此行是多余的
还是我误解了整个继承权的事情?也许override
不会覆盖所有内容
Bar::Delta();
是一个函数调用。这不就是它看起来的样子吗
它调用的是Delta
的基类版本,除了Foo
版本所做的任何额外工作之外,它还显式地将其限定为Bar::Delta
也许覆盖并不能覆盖一切
Bar::Delta();
override
关键字只要求编译器验证您是否真的重写了一个虚拟函数——否则,很容易意外地编写一个不重写任何内容的新函数(例如,由于参数类型略有不同,或者某个版本是const限定的,或者您更改了基类而忘记更新派生类,或者…)
在这里,您正在重写虚拟函数。这不会阻止基类实现的存在,正如您所看到的,您仍然可以调用它
<>你可以(也应该)测试你自己对这类事情的直觉。考虑下面的琐碎测试代码。你认为它能做什么? 现在实际运行它。你是对的吗?如果不是,哪部分是意外的
#include <iostream>
using namespace std;
struct Bar {
virtual void Delta() {
cout << "Bar::Delta\n";
}
};
struct Foo : public Bar {
void Delta() override
{
cout << "Foo::Delta\n";
Bar::Delta();
}
};
int main()
{
cout << "b.Delta()\n";
Bar b;
b.Delta();
cout << "f.Delta()\n";
Foo f;
f.Delta();
cout << "pb->Delta()\n";
Bar *pb = &b;
pb->Delta();
cout << "pb->Delta()\n";
pb = &f;
pb->Delta();
}
#包括
使用名称空间std;
结构条{
虚空增量(){
库特
也许覆盖并不能覆盖一切
Bar::Delta();
重写说明符可用于在重写函数时进行编译时检查,以确定被重写的函数是虚拟的且实际上正在被重写
线条栏::Delta();存在的原因
此行调用baseDelta
函数,该函数可能有一些有用的任务要执行,即使您已经覆盖了它
一个简单的例子:
class Base
{
public:
virtual ~Base() {}
virtual void Foo()
{
// run tasks that are common to all derived types
}
};
class Derived : public Base
{
public:
void Foo() override
{
Base::Foo(); // we have to call this explicitly
// run tasks specific to the derived type
}
};
这是一种常见的模式。事实上,调用重写成员函数的:
语法专门针对这种情况
基类中的成员函数执行一些可以独立于派生类执行的计算或操作,并让派生类执行特定于派生的操作,这是非常常见的
下面是一个虚构的例子:
class Stock {
protected:
double totalDividend;
double baseDividend;
double adjustmentFactor;
public:
Stock(double d, double a)
: baseDividend(d), totalDividend(d), adjustmentFactor(a) {
}
virtual void double ComputeDividend() {
return totalDividend * adjustmentFactor;
}
};
class SpecialStock {
private:
double specialDividend;
public:
SpecialStock(double d, double sd, double a)
: Stock(d, a), specialDividend(sd) {
}
virtual void double ComputeDividend() override {
// Do some preparations
totalDividend = baseDividend + specialDividend;
// Call the overridden function from the base class
return Stock::ComputeDividend();
}
};
您似乎误解了override
在c++
中的含义。对于您的情况,您不应该为它操心。它就像一个普通的虚拟函数。override
关键字只是一种确保基类具有匹配函数的安全机制。除了语义编译时检查之外,它不会更改任何内容
防范典型的不匹配有些有用,例如const
与非const
版本等
虚拟方法机制不会替换原始成员函数。它仍然存在于派生的对象中。实际情况是引入了一个间接级别,因此对base.foo()
的调用使用函数指针来调用正确的实现,即派生的::foo()
在你的例子中。但是Base::Foo()
仍然存在,这是“访问”它的语法。你可以通过搜索virtual
方法上的资料来查看它到底是如何工作的。Foo中的Delta是一个虚拟方法,它“做一些事情”,然后调用基类的Delta实现
override不会重写任何内容,将方法声明为虚拟方法会执行此操作。override只是让编译器在父类没有Delta方法的情况下抛出语法错误。有时基类有一些有用的任务要执行,而不管是否被重写。Bar::Delta()
调用Bar::Delta
-此函数仍然存在,覆盖
只是为了确保实际存在具有相同签名的虚拟
函数-如果没有,将导致编译错误。