[英]Call base virtual method by pointer to function from derived class
I need to call the base method A::foo() from derived class by pointer. 我需要通过指针从派生类调用基本方法A :: foo()。
#include <iostream>
struct A{
virtual void foo() { std::cout << "A::foo()" << std::endl; }
};
struct B:A{
virtual void foo() { std::cout << "B::foo()" << std::endl; }
void callBase(void (A::*f)()){
(this->*f)();
}
};
int main(){
B* p=new B();
p->callBase(&A::foo);
}
This code output "B::foo". 此代码输出“B :: foo”。 Is it possible to call A::foo() by pointer to method?
是否可以通过指向方法的方法调用A :: foo()?
Well, you can do something similar using some tricks with overwriting the value of this
. 那么,你可以使用一些技巧与覆盖的价值做类似的事情
this
。 You probably should never try to do that though, vtable
pointers aren't meant to be modified by hand. 你可能永远不应该尝试这样做,但
vtable
指针并不意味着手工修改。
To do what you described, we need to have the pointer to A's vtable
. 要做你所描述的,我们需要指向A的
vtable
。 Our object p
has only pointer to B's vtable
, so we need to store second pointer in a field within A's constructor. 我们的对象
p
只有指向B的vtable
指针,所以我们需要在A的构造函数中的一个字段中存储第二个指针。
Here is the code: 这是代码:
#include <iostream>
struct A{
virtual void foo() { std::cout << "A::foo()" << std::endl; }
int *a_vtable_ptr;
// First, save value of A's vtable pointer in a separate variable.
A() { a_vtable_ptr = *(int**)this; }
};
struct B:A{
virtual void foo() { std::cout << "B::foo()" << std::endl; }
void callBase(void (A::*f)()){
int *my_vtable_ptr = *(int**)this;
// Then modify vtable pointer of given object to one that corresponds to class A.
*(int**)this = a_vtable_ptr;
(this->*f)(); // Call the method as usual.
// Restore the original vtable pointer.
*(int**)this = my_vtable_ptr;
}
};
// Function main() is not modified.
int main(){
B* p=new B();
void (A::*f)() = &A::foo;
p->callBase(f);
}
Output: 输出:
A::foo()
Process finished with exit code 0
Virtual methods are designed to implement polymorphism and pointers to virtual methods supports their polymorphic behavior. 虚方法旨在实现多态,而指向虚方法的指针支持其多态行为。 But you given the possibility to call the base method by explicitly calling
p->A::foo()
. 但是您可以通过显式调用
p->A::foo()
来调用base方法。
So if you want to call base method by pointer, you should make it non-virtual (as @PasserBy mentioned in comments). 因此,如果要通过指针调用基本方法,则应将其设置为非虚拟(如注释中提到的@PasserBy)。
Code example: 代码示例:
struct A {
virtual void foo() { std::cout << "A::foo()" << std::endl; }
void bar() { std::cout << "A::bar()" << std::endl; }
void callBase(void (A::*f)()) { (this->*f)(); }
};
struct B : A {
virtual void foo() { std::cout << "B::foo()" << std::endl; }
void bar() { std::cout << "B::bar()" << std::endl; }
};
int main()
{
A* p = new B();
p->foo();
p->bar();
p->callBase(&A::foo);
p->callBase(&A::bar);
p->A::foo();
p->A::bar();
}
Output: 输出:
B::foo()
A::bar()
B::foo()
A::bar()
A::foo()
A::bar()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.