我正在查看一些C ++示例代码,它有效地具有以下内容:
class Foo : public mynamespace::Bar
{
public:
Foo()
{
// Do some stuff
}
void Delta() override
{
// Do some stuff
Bar::Delta();
}
};
我无法理解为什么行Bar::Delta();
存在。鉴于类Foo
继承了类Bar
,那么当调用Foo::Delta()
时,这会覆盖Bar::Delta()
中存在的任何内容,因此该行是多余的。
或者我误解了整个继承的事情?也许override
不会覆盖所有内容?
答案 0 :(得分:3)
Bar::Delta();
是一个函数调用。这不是它的样子吗?
它正在调用Delta
的基类版本 - 通过明确地将其Bar::Delta
- 添加到以及Foo
版本所做的任何额外内容。
也许覆盖不会覆盖所有内容?
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();
}
答案 1 :(得分:3)
这是一种常见的模式。实际上,调用重写成员函数的::
语法专门针对这种情况。
基类中的成员函数执行某些计算或操作是非常常见的,这些计算或操作可以独立于派生类完成,并让派生类执行特定于派生的事情。
这是一个虚构的例子:
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();
}
};
答案 2 :(得分:1)
也许覆盖不会覆盖所有内容?
当覆盖一个被覆盖的函数是虚拟的并且实际上被覆盖的函数时,覆盖说明符可用于进行编译时检查。
为什么行Bar :: Delta();存在
此行调用基本Delta
函数,即使您已覆盖它,也可能会执行一些有用的任务。
一个简单的例子:
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
}
};
答案 3 :(得分:1)
您似乎误解了override
中c++
的含义。对于你的情况,你不应该为此烦恼。这就像一个普通的虚拟功能。 override
关键字只是一种安全机制,可确保基类具有匹配功能。除了语义编译时检查之外,它不会改变任何内容。
防止典型的不匹配有点有用,例如const
与非const
版本等。
虚方法机制不会替换原始成员函数。它仍然存在于Derived
对象中。会发生什么情况是引入了间接级别,因此对base.foo()
的调用使用函数指针来调用正确的实现,在您的情况下为Derived::Foo()
。但是Base::Foo()
仍然存在,这是“访问”它的语法。您可以通过在virtual
方法上搜索材料来查找其工作原理。
答案 4 :(得分:1)
foo中的Delta是一种虚拟方法,可以做一些事情&#34;然后调用基类的Delta实现。
覆盖不会覆盖任何内容,将该方法声明为虚拟方式。 override只是让编译器在父类没有Delta方法的情况下抛出语法错误。