将指向一个派生类的方法的指针转换为指向基类方法的指针 [英] Casting a pointer to a method of a derived class to a pointer to a method of a base class
问题描述
将指向某个派生类方法的指针转换为指向基类方法的指针是合法的,即使基类没有声明任何方法,特别是casted方法的类型通过类型基类的对象调用,遵循:
Is it legal to cast a pointer to a method of derived class to a pointer to a method of base class, even though the base class does not declare any methods, especially of the "casted" method is called through an object of type base class, as follows:
// works in VS 2008 and g++ 4.5.3
struct Base
{
};
struct Fuu : public Base
{
void bar(){ std::cout << "Fuu::bar" << std::endl; }
void bax(){ std::cout << "Fuu::bax" << std::endl; }
};
struct Foo : public Base
{
void bar(){ std::cout << "Foo::bar" << std::endl; }
void bax(){ std::cout << "Foo::bax" << std::endl; }
};
typedef void (Base::*PtrToMethod)();
int main()
{
PtrToMethod ptr1 = (PtrToMethod) &Foo::bax;
PtrToMethod ptr2 = (PtrToMethod) &Fuu::bax;
Base *f1 = new Foo;
Base *f2 = new Fuu;
(f1->*ptr1)();
(f2->*ptr2)();
}
推荐答案
目标对象是逆变的,因为这个
实际上是传递给函数的参数,并且参数理论上是逆变的(如果函数可以使用 Base *
,它可以安全地插入任何只提供 Derived *
作为实际参数的算法。
It's worth noting that the reason the target object is contravariant is because this
is effectively a parameter being passed to the function, and parameters are, in theory, contravariant (if the function can use a Base*
, it can be safely plugged into any algorithm which provides only Derived*
as the actual arguments).
但是,对于任意参数,如果基本子对象未放置在派生类布局的开头,则可能需要垫片来调整指针。对于指向成员的指针,此
指针的指针调整内置到语言中。 (因此,指向成员的类与虚拟继承的指针可能会非常大)
However, for arbitrary parameters, a shim may be needed to adjust the pointer, if the base subobject is not placed at the beginning of the derived class layout. With pointer-to-members, pointer adjustment for the this
pointer is built into the language. (And for this reason, pointer-to-member-of-class-with-virtual-inheritance can get quite large)
这篇关于将指向一个派生类的方法的指针转换为指向基类方法的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!