Наложение наследования на С++

У меня есть базовый класс следующим образом:

class point    //concrete class
{
 ...    //implementation
}

class subpoint : public point  //concrete class
{
...     //implementation
}

Как мне отбрасывать из точечного объекта в объект подпункта? Я пробовал все три из следующих:

point a;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
subpoint b = (subpoint)a;

Что не так с этими приведениями?

Ответ 1

Как мне отбрасывать из объекта точки в объект подпункта?

Вы не можете; если только point не имеет оператора преобразования, или subpoint имеет конструктор преобразования, и в этом случае типы объектов могут быть преобразованы без необходимости приведения.

Вы можете использовать ссылку point (или указатель) на ссылку subpoint (или указатель), если упомянутый объект действительно имеет тип subpoint:

subpoint s;

point & a = s;
subpoint & b1 = static_cast<subpoint&>(a);
subpoint & b2 = dynamic_cast<subpoint&>(a);

Первый (static_cast) более опасен; нет проверки, что преобразование действительно, поэтому, если a не относится к subpoint, то использование b1 будет иметь поведение undefined.

Второй (dynamic_cast) безопаснее, но работает, только если point является полиморфным (то есть, если он имеет виртуальную функцию). Если a относится к объекту несовместимого типа, тогда он выдает исключение.

Ответ 2

В первом примере dynamic_cast работает только в том случае, если в базовом классе есть хотя бы один виртуальный метод. И если объект фактически не относится к типу, который вы пытаетесь выполнить, это приведет к NULL.

Для второго примера вам нужно &a вместо a, но как только вы исправили, что получите поведение undefined, потому что тип объекта неверен.

Третий пример требует operator subpoint() метода в point для преобразования при создании копии.

Ответ 3

В целом, это не сработает, потому что point не является subpoint; верно только обратное. Однако есть и другие проблемы.

В порядке:


subpoint* b = dynamic_cast<subpoint*>(&a);

dynamic_cast работает только с полиморфными типами, т.е. типами, объявляющими хотя бы одну виртуальную функцию. Я предполагаю, что point не имеет виртуальных функций, что означает, что он не может использоваться с dynamic_cast.


subpoint* b = (subpoint*)a;

Для этого приведения point необходимо объявить оператор преобразования subpoint *, например, point::operator subpoint *().


subpoint b = (subpoint)a;

Для этого приведения в действие нужно указать, что оператор преобразования в subpoint или subpoint должен иметь конструктор, который принимает параметр, который можно преобразовать из point.

Ответ 4

Цель динамического приведения - "проверять во время выполнения, если объект имеет определенный тип в иерархии". Теперь давайте посмотрим, что у вас есть:

  • У вас есть точечный объект. Не подпункт.
  • Вы запрашиваете динамическое копирование, если объект является подпунктовой. Это не так.
  • Поскольку его не подпункт, dynamic_cast терпит неудачу - его способ сказать вам, что объект не тот тип, который вы пытаетесь передать.

В отличие от этого, это сработало бы:

subpoint c;
point *a = &c;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;

Ответ 5

a не может быть превращено в subpoint. что реализации там нет.

Ответ 6

Что не так с этими приведениями?

Тот факт, что вы пытаетесь сделать это. A point не является subpoint, я был бы удивлен, если бы это сработало.