将指向派生类的方法的指针强制转换为指向基类方法的指针

Olu*_*ide 2 c++ function-pointers

指向派生类的方法的指针强制转换为指向基类方法的指针是合法的,即使基类没有声明任何方法,尤其是"casted"方法通过类型基类的对象调用,如下:

// 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)();
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*igt 5

值得注意的是,目标对象是逆变的原因是因为this它实际上是一个传递给函数的参数,而且理论上参数是逆变的(如果函数可以使用a Base*,它可以安全地插入到任何只提供的算法中)Derived*作为实际论点).

但是,对于任意参数,如果基础子对象未放置在派生类布局的开头,则可能需要垫片来调整指针.使用指向成员的指针,指针的指针调整this内置于语言中.(并且由于这个原因,指向成员的类与虚拟继承可以变得非常大)

  • @gx_:从理论上讲,指向成员变量的指针*是一个函数,将强类型对象地址映射到强类型子对象地址.在存在虚拟继承的情况下,这些函数有资格作为方法,因为它们是动态分派的.在大多数实现中,从不使用实际的函数调用,子对象访问代码直接插入到使用点,但这与内联任何其他函数没有什么不同. (2认同)