c++选择函数的继承优先级
c++ inheritance priorities of choosing functions
我似乎无法理解编译器如何优先处理哪个函数。
这是一个示例代码:
#include <iostream>
using namespace std;
class A{
public:
int f() {return 1;}
virtual int g() {return 2;}
};
class B: public A {
public:
int f() {return 3;}
virtual int g() {return 4;}
};
class C: public A{
public:
virtual int g() {return 5;}
};
int main () {
A *pa;
B b;
C c;
pa = &b;
cout<< pa -> f()<<endl<<pa -> g() << endl;
pa = &c;
cout<< pa -> f() << endl; cout<< pa -> g() << endl;
return 0;
}
每次调用哪个函数(g() 和 f()),为什么?
在第一个序列中,它将调用 A::f()
和 B::g()
。
在第二个序列中,它将调用 A::f()
和 C::g()
。
原因是 f()
作为非虚拟方法是在编译时根据变量类型(指向 A
的指针)解析的。 g()
在 A
中被标记为虚拟方法,因此运行时解析已完成,它将始终调用真实实例的方法(B
或 C
)。
pa->f()
将始终调用 A::f()
,无论您将 pa
指向什么,因为 pa
是 A*
而 A::f
不是虚拟.
pa->g()
将调用 A::g()
、B::g()
或 C::g()
,具体取决于 pa
指向使用 polymorphism 的内容,因为 A::g
是虚拟:
- 如果
pa
指向一个B
(第一个序列),它将调用B::g()
。
- 如果
pa
指向一个C
(第二个序列),它将调用C::g()
.
当您说函数是 virtual
时,您告诉编译器使用后期绑定而不是静态绑定。
所以在编译期间 A::f()
将是静态绑定的,所以调用哪个方法体是固定的。
另一方面 A::g()
在编译期间不会绑定到任何方法体 time.It 将在运行时决定调用哪个方法体(使用 vptr)。
A *pa; //no matter what object you assign to pa, A::fa() will always be called
pa = &b;
pa->f();//calls A::f()
pa->g();// remember what function body to be called will be decided at runtime.
//will call B::f()
pa = &c;
pa->g(); //will call C::g()
我似乎无法理解编译器如何优先处理哪个函数。 这是一个示例代码:
#include <iostream>
using namespace std;
class A{
public:
int f() {return 1;}
virtual int g() {return 2;}
};
class B: public A {
public:
int f() {return 3;}
virtual int g() {return 4;}
};
class C: public A{
public:
virtual int g() {return 5;}
};
int main () {
A *pa;
B b;
C c;
pa = &b;
cout<< pa -> f()<<endl<<pa -> g() << endl;
pa = &c;
cout<< pa -> f() << endl; cout<< pa -> g() << endl;
return 0;
}
每次调用哪个函数(g() 和 f()),为什么?
在第一个序列中,它将调用 A::f()
和 B::g()
。
在第二个序列中,它将调用 A::f()
和 C::g()
。
原因是 f()
作为非虚拟方法是在编译时根据变量类型(指向 A
的指针)解析的。 g()
在 A
中被标记为虚拟方法,因此运行时解析已完成,它将始终调用真实实例的方法(B
或 C
)。
pa->f()
将始终调用 A::f()
,无论您将 pa
指向什么,因为 pa
是 A*
而 A::f
不是虚拟.
pa->g()
将调用 A::g()
、B::g()
或 C::g()
,具体取决于 pa
指向使用 polymorphism 的内容,因为 A::g
是虚拟:
- 如果
pa
指向一个B
(第一个序列),它将调用B::g()
。 - 如果
pa
指向一个C
(第二个序列),它将调用C::g()
.
当您说函数是 virtual
时,您告诉编译器使用后期绑定而不是静态绑定。
所以在编译期间 A::f()
将是静态绑定的,所以调用哪个方法体是固定的。
另一方面 A::g()
在编译期间不会绑定到任何方法体 time.It 将在运行时决定调用哪个方法体(使用 vptr)。
A *pa; //no matter what object you assign to pa, A::fa() will always be called
pa = &b;
pa->f();//calls A::f()
pa->g();// remember what function body to be called will be decided at runtime.
//will call B::f()
pa = &c;
pa->g(); //will call C::g()