У полиморфных бросков в стиле C есть накладные расходы? - PullRequest
4 голосов
/ 23 февраля 2011
  • Имеет ли приведение указателя на экземпляр Dervived класса к базовому классу экземпляров какие-либо накладные расходы времени выполнения в C ++, или это разрешается во время компиляции?

  • Если он есть, что именно нужно вычислить в операции литья?

Пример:

class Foo;
class Bar : public Foo;

Bar* y = new Bar;
Foo* x = (Foo*) y;

(я знаю, что должен использовать приведение в стиле C ++ и что ответ, вероятно, для них одинаков)

Ответы [ 4 ]

5 голосов
/ 23 февраля 2011

Да, хотя это незначительно.

В этом случае приведение в стиле C интерпретируется как static_cast, что может привести к корректировке указателя.

struct Base {};

struct Derived: Base { virtual ~Derived(); } // note: introduced a virtual method

int main()
{
  Derived derived;
  Base* b = &derived;
  Derived* d = (Derived*) b;

  void* pb = b;
  void* pd = d;

  printf("%p %p", pb, pd);

  return 0;
}

Это накладные расходы происходят, когда базовый подобъект не выровнен по тому же адресу, что и производный объект, что происходит, когда:

  • Представляем первый виртуальный метод
  • с использованием мульти-наследования

Конечно, корректировка указателя обычно считается пренебрежимо малой, и компилятор должен быть достаточно умен, чтобы устранить ее, если она все равно не нужна (настройка 0).

Примечание: это зависит от реализации, а не предписано стандартом

5 голосов
/ 23 февраля 2011
Foo* x = (Foo*) y;

Вам не нужно разыгрывать Bar* на Foo*. Приведение из Derived в Base неявно:

Foo* x = y ; // is enough!

Что касается полиморфного броска, приведение в стиле C не эквивалентно dynamic_cast. C ++ dynamic_cast - это совершенно новая функция, добавленная в язык, и ей нет соответствия в приведении в стиле C.

Приводит указатель на экземпляр дервивированного класса к инстансам базовый класс имеет какие-либо накладные расходы во время выполнения в C ++, или это решено в время компиляции?

Приведение из производного к базовому разрешается во время компиляции, если вы делаете, как я делал выше. Так что у него нет времени выполнения.

2 голосов
/ 23 февраля 2011
Приведения

C не имеют никаких накладных расходов во время выполнения. Единственная операция приведения, которая создает накладные расходы времени выполнения, - это dynamic_cast<>(), поскольку она проверяет информацию о типе среды выполнения.

1 голос
/ 23 февраля 2011

См. Ответ на аналогичный вопрос: обычное приведение к статическому приведению к динамическому приведению

Подводя итог: приведение в стиле C не имеет накладных расходов во время выполнения, поскольку оно пробует множество методов приведения C ++, кроме dynamic_cast (что влечет за собой штраф во время выполнения).

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