Как я могу сформировать окончательную ссылку на нефинальный класс? - PullRequest
2 голосов
/ 27 января 2020

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

Предположим, теперь у меня есть некоторый не final класс T с виртуальными функциями и / или базовыми классами. Предположим также, что у меня есть ссылка на экземпляр этого класса. Как я могу сказать компилятору, что эта конкретная ссылка относится к полностью производному завершенному объекту, а не к базовому подобъекту более производного типа?

Мои мотивы - это такие классы, как optional и vector. Если я призываю optional<T>::operator*(), я получаю T&. Однако я с уверенностью знаю, что эта ссылка действительно T, а не какой-то более производный объект. То же относится и к vector<T> и ко всем способам доступа к его элементам.

Я думаю, что было бы хорошей оптимизацией пропустить динамическую диспетчеризацию c в таких случаях, особенно в режиме отладки и на недостаточно умных компиляторах для просмотра реализаций optional и vector и девиртуализации. звонки.

1 Ответ

1 голос
/ 28 января 2020

Формально вы можете сделать это:

void final(A &a) {
  static_cast<A*>(dynamic_cast<void*>(&a))->foo();
}

dynamic_cast<void*> возвращает указатель на наиболее производный тип (а static_cast из void* не может выбрать полиморф c базовый класс), поэтому компилятор может знать, что вызывается A::foo. Однако компиляторы, похоже, не пользуются этой информацией; они даже генерируют очевидные дополнительные инструкции для фактического выполнения динамического приведения c (даже если это, конечно, будет неопределенным поведением, если оно потерпит неудачу).

Вы, конечно, можете девиртуализировать Вы сами пишете a.A::foo() всякий раз, когда позволяют многословие и обобщенность.

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