[英]Overriding Non-Virtual methods?
Below is some code that is intended to show when the virtual method is overridden. 下面是一些代码,用于显示重写虚拟方法的时间。 It outputs: BBAABA Is this correct?
它输出:BBAABA这是正确的吗? I thought the bar method could not be overridden...?
我以为bar方法无法被覆盖......?
#include <iostream>
using namespace std;
class A
{
public:
virtual void foo(){cout<<"A"<<endl;}
void bar(){cout<<"A"<<endl;}
};
class B : public A
{
public:
void foo(){cout<<"B"<<endl;}
void bar(){cout<<"B"<<endl;}
};
int main()
{
B b;
A * pA = new A;
A * pA2 = &b;
b.foo(); b.bar();
pA->foo(); pA->bar();
pA2->foo(); pA2->bar();
}
I don't see anything wrong: 我没有看到任何错误:
B b;
b.foo(); b.bar();
You declare and initialize an instance of B
, compile type is B
, runtime type is B
. 声明并初始化
B
的实例,编译类型为B
,运行时类型为B
Polymorphism is not needed (nor it can be achieved, since there is no pointer involved). 不需要多态性(也不能实现,因为没有涉及指针)。
A * pA = new A;
pA->foo(); pA->bar();
You declare a pointer to A
and initialize it with an instance of A
. 你声明的指针,
A
与实例初始化A
。 Polymorphism works even if it is not necessary in this case, so foo()
and bar()
from A
are called. 即使在这种情况下不需要多态性也可以工作,因此调用来自
A
foo()
和bar()
。
A * pA2 = &b;
pA2->foo(); pA2->bar();
You declare a pointer to A
and initialize it with a reference to B
. 您声明一个指向
A
的指针,并使用对B
的引用对其进行初始化。 Compile time type is A*
, runtime type is B*
. 编译时间类型为
A*
,运行时类型为B*
。 Polymorphism through virtual function is applied, so the virtual method is B::foo()
while the non-virtual is A::bar()
应用通过虚函数的多态性,因此虚方法是
B::foo()
而非虚方法是A::bar()
b.foo()
gives B
, b.foo()
给出B
,
b.bar()
also gives B
which hides A::bar()
. b.bar()
也给出了隐藏A::bar()
B
It is not overriding, it is name hiding. 它不是压倒一切,它隐藏着名字。
pA->foo()
gives A
, pA->bar()
gives A
, pA->foo()
给出A
, pA->bar()
给出A
,
pA2->foo()
gives B
since it is a virtual function. pA2->foo()
给出B
因为它是一个虚函数。
pA2->bar()
gives A
since it is not a virtual function. pA2->bar()
给出A
因为它不是虚函数。 It is statically linked and it calls A::bar()
. 它是静态链接的,它调用
A::bar()
。
The first two outputs should both be B because you are calling foo() and bar() on an object of type B. Since you're not using a pointer, the compiler knows it's an object of type B and therefore does not need to consult the vtable to invoke the method, so even though bar() is not virtual, the compiler knows to use the B implementation. 前两个输出都应该是B,因为你在类型B的对象上调用foo()和bar()。因为你没有使用指针,编译器知道它是B类型的对象,因此不需要请参考vtable来调用该方法,因此即使bar()不是虚拟的,编译器也知道使用B实现。
The next two outputs should both be A because you're calling foo() and bar() on a pointer to an object of type A. In this case, foo() is virtual, and the vtable is pointing to the A implementation of the method. 接下来的两个输出都应该是A,因为你在指向类型A的对象的指针上调用foo()和bar()。在这种情况下,foo()是虚拟的,而vtable指向A的实现方法。 bar() is not virtual, so the compiler decides to use the A implementation.
bar()不是虚拟的,因此编译器决定使用A实现。
The final two outputs should be B and A because you're calling foo() and bar() on a pointer to an object of type B. In this case, foo() is virtual, and the vtable is pointing to the B implementation of the method. 最后两个输出应该是B和A,因为你在指向类型B的对象的指针上调用foo()和bar()。在这种情况下,foo()是虚拟的,vtable指向B实现方法。 bar() is not virtual, so the compiler decides to use the A implementation since you're using a pointer to an object of type A.
bar()不是虚拟的,因此编译器决定使用A实现,因为您正在使用指向A类型对象的指针。
It is correct, the pA2->bar() call is not overridden. 这是正确的,pA2-> bar()调用不会被覆盖。 Even though it's a B object, you cast it to an A and the compiler calls A member functions for A classes.
即使它是一个B对象,也可以将它转换为A,编译器调用A类的成员函数。
foo() is virtual, so included inside of the class B is a pointer to which version of foo() is correct for the class, regardless of where it's cast to. foo()是虚拟的,因此包含在类B中的是指向哪个版本的foo()对于类是正确的指针,无论它被转换到何处。
This inclusion is called a pointer to a virtual function table. 此包含称为指向虚函数表的指针。 As soon as your class has on virtual member, a static function table is created for it (and also will include any other subsequent virtual functions), additionally a constant hidden member pointer points to this table.
只要您的类具有虚拟成员,就会为其创建一个静态函数表(并且还将包括任何其他后续虚函数),另外一个常量隐藏成员指针指向该表。 When you cast an object the function table is unchanged, any virtual functions will stay 'attached' to the original type.
当您转换对象时,函数表不会更改,任何虚函数都将保持“附加”到原始类型。
PS, don't forget to delete pA... you currently have a memory leak :) PS,别忘了删除pA ...你目前有内存泄漏:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.