음, this
의 값을 덮어 쓰면서 몇 가지 트릭을 사용하여 비슷한 작업을 수행 할 수 있습니다. 당신은 아마 그렇게하려고 시도해서는 안되며, vtable
포인터는 수작업으로 수정 될 의도가 없습니다.
설명 된대로하려면 A의 vtable
에 대한 포인터가 있어야합니다. 객체 p
에는 B의 vtable
에 대한 포인터 만 있으므로 A의 생성자 내의 필드에 두 번째 포인터를 저장해야합니다.
이
#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);
}
출력 :
A::foo()
Process finished with exit code 0
나는 당신이 할 수 있다고 생각하지 않습니다. 그러나, 나는 과거에 잘못되었습니다 :) 나보다 지식이 많은 사람이 길을 알고 있기를 바랍니다. –
'p-> :: foo();와 같이 직접 호출 할 수는 있지만 멤버 함수에 대한 포인터는 아닙니다 (가상 함수의 포인트라고 생각합니다). –
저는이 작업을 수행하는 가상이 아닌'bar'를 사용하고'foo' 대리자를'bar'에 위임함으로써이 문제를 해결할 것이라고 믿습니다.'callBase'는'bar'를 호출합니다. 다형성은'B'가 항상 자신의'foo'를 호출해야 함을 의미하므로 더 논리적입니다. –