Вызов методов производного класса из указателя в базовый класс через reinterpret_casting указатель метода. Это UB? - PullRequest
1 голос
/ 09 июля 2019

Имея указатель на объект производного типа, назначенный указателю его базового класса, я обнаружил, что вы можете reinterpet_cast метод из производного класса в указатель базового класса, даже если базовый класс не не имеет таких функций (виртуальных, скрытых или других). И это может быть разыменовано и вызвано оттуда, и это "просто работает". Но я хотел бы убедиться, что это не UB. Это UB? Это портативный?

Пример компиляции:

#include <cstdio>

struct A { /* no foo method */ };
struct B : public A { void foo(void){printf("foo");} };

typedef void (B::*B_FOO_PTR)( void );
typedef void (A::*A_FOO_PTR)( void );

int main ( void ) {
    B b;
    A* a = &b;

    // address of a and b are identical

    B_FOO_PTR b_ptr = &B::foo;
    // (a->*b_ptr)(); // COMPILE ERROR: calling B method from A. Not Allowed, but...

    A_FOO_PTR a_ptr = reinterpret_cast<A_FOO_PTR>(b_ptr);
    (a->*a_ptr)(); // works, outputs "foo"

    return 0;
}

1 Ответ

4 голосов
/ 09 июля 2019

Это неопределенное поведение.Единственные преобразования функций указателя на член, в которых вы можете вызвать результат:

  • преобразование туда и обратно и
  • указатель на элемент базы в указатель-to-member-производный.

Вы пытаетесь инвертировать вторую точку, которая исключена из этого списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...