Неполный класс: преобразовать void* в указатель на тип класса через dynamic_cast

У меня есть 2 класса A и B. B является производным от A. A имеет член указателя на функцию, для которого аргумент является объектом B. Классы определяются следующим образом:

class B;
typedef double (*func_ptr)(B *);

class A
{
  private:
    func_ptr func;
};

class B: public A
{
  private:
    double C;
};

Когда я пытаюсь динамически преобразовать void* в A* или B*, я получаю следующую ошибку:

void *v_ptr;
A *a_ptr = dynamic_cast<A*>(v_ptr);
B *b_ptr = dynamic_cast<B*>(v_ptr);

error: the operand of a pointer dynamic_cast must be a pointer to a complete class type

Я понятия не имею, почему это происходит. Ни в одном из классов нет виртуальных методов. Я знаю, что предварительное объявление класса нельзя использовать для объявления членов, но здесь оно используется для определения указателя.

Кто-нибудь может объяснить, почему я получаю эту ошибку?


person Harshad    schedule 12.12.2017    source источник
comment
Когда я пытаюсь динамически преобразовать пустоту* - это не разрешено с dynamic_cast. Вся твоя проблема в этом предложении.   -  person StoryTeller - Unslander Monica    schedule 12.12.2017
comment
Вероятно, ошибка транскрипции, но если нет, то эта точка с запятой private; вам не поможет.   -  person user4581301    schedule 12.12.2017
comment
@ user4581301 Да, извините, это личное:   -  person Harshad    schedule 12.12.2017


Ответы (2)


Вы не можете преобразовать void* с помощью dynamic_cast, выражение, требуемое dynamic_cast, должно ссылаться к полному типу класса, а void — нет.

(выделено мной)

lvalue полного типа класса, если new_type является ссылкой, prvalue указателя на полный тип класса, если new_type является указателем.

Кстати: тип преобразования также должен относиться к полному типу класса.

указатель на полный тип класса, ссылка на полный тип класса или указатель на (необязательно cv-qualified) void

person songyuanyao    schedule 12.12.2017
comment
Спасибо. Теперь я понимаю. Я должен использовать static_cast - person Harshad; 12.12.2017

Операнд dynamic_castдолжен быть указателем на полный тип класса ([expr. динамический.cast]):

  1. Результат выражения dynamic_­cast<T>(v) является результатом преобразования выражения v в тип T....
  2. Если T является типом указателя, v должно быть значением prvalue указателя на полный тип класса, а результатом является значение prvalue типа T...

Кроме того, действительно неясно, почему вы вообще используете dynamic_cast. Классы в вашем примере не полиморфны. Никаких виртуальных функций не предвидится.

person StoryTeller - Unslander Monica    schedule 12.12.2017
comment
Спасибо. Теперь я понимаю. Я должен использовать static_cast - person Harshad; 12.12.2017