在 C++ 中,如果函数重写了虚函数,它是否自动成为虚函数?
我希望如果 foo
在类 D
中声明,但未标记为 virtual,那么以下代码将调用 foo
中的实现code>D(无论 d
的动态类型如何)。
D& d = ...;
d.foo();
然而,在下面的程序中,情况并非如此。谁能解释一下吗?如果一个方法重写了虚函数,它会自动成为虚拟方法吗?
#include <iostream>
using namespace std;
class C {
public:
virtual void foo() { cout << "C" << endl; }
};
class D : public C {
public:
void foo() { cout << "D" << endl; }
};
class E : public D {
public:
void foo() { cout << "E" << endl; }
};
int main(int argc, char **argv)
{
E& e = *new E;
D& d = *static_cast<D*>(&e);
d.foo();
return 0;
}
上述程序的输出是:
E
I would expect that if foo
is declared in class D
, but not marked virtual, then the following code would call the implementation of foo
in D
(regardless of the dynamic type of d
).
D& d = ...;
d.foo();
However, in the following program, that is not the case. Can anyone explain this? Is a method automatically virtual if it overrides a virtual function?
#include <iostream>
using namespace std;
class C {
public:
virtual void foo() { cout << "C" << endl; }
};
class D : public C {
public:
void foo() { cout << "D" << endl; }
};
class E : public D {
public:
void foo() { cout << "E" << endl; }
};
int main(int argc, char **argv)
{
E& e = *new E;
D& d = *static_cast<D*>(&e);
d.foo();
return 0;
}
The output of the above program is:
E
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
标准 10.3.2 (class.virtual) 说:
Standard 10.3.2 (class.virtual) says:
快速回答可能是否定的,但正确的答案是是
C++ 不知道函数隐藏,因此覆盖没有 virtual 关键字的虚函数也标记该函数为虚函数。
Quick answer may be no, but correct answer is yes
C++ doesn't know about function hiding, so overriding virtual function without virtual keyword marks that function virtual too.
您没有创建 e 对象的任何副本并将其放入 d 中。因此 d.foo() 遵循正常的多态行为并调用派生类方法。在基类中声明为虚拟的方法在派生类中也自动变为虚拟。
You are not creating any copy of the object of e and putting it in d. So d.foo() follows normal polymorphic behavior and calls derived class method. A method which is declared as virtual in the base class becomes automatically virtual in the derived class also.
输出(“E”)的行为与人们所期望的完全一样。
原因:
该引用的动态(即运行时)类型是 E。您正在对 D 进行静态向上转换,但这当然不会改变对象的实际类型。
这就是虚拟方法和动态调度背后的理念:您可以看到正在实例化的类型的行为,在本例中为 E。
The output ("E") behaves exactly as one would expect it to behave.
The reason:
The dynamic (i.e. runtime) type of that reference is E. You are doing a static upcast to D, but that does not change the actual type of the object of course.
That's the very idea behind virtual methods and dynamic dispatches: You see the behavior of the type you were instantiating, which is E, in this case.