typeid для полиморфных указателей?

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

(Это дополнительный вопрос от typeid для полиморфных типов)

11

Решение

Ваш вопрос страдает от неправильного использования терминологии. Язык C ++ проводит очень четкое различие между самими указателями и объектами, на которые указывают эти указатели. Типы указателей не являются полиморфными. В самом указателе нет ничего полиморфного. Что действительно может быть полиморфным, так это тип, на который указывает указатель. Когда указатель указывает на полиморфный тип, мы часто [неофициально] называем его полиморфный указатель (просто как сокращение для «указателя, который указывает на полиморфный тип»). Но когда дело доходит до таких вещей, как typeidони видят вещи очень формально. За typeid типы указателей никогда не бывают полиморфными.

И компилятор не определяет, является ли указатель полиморфным или нет во время выполнения. Это простое различие всегда сразу известно во время компиляции. Опять же, указатель называется полиморфный если он объявлен как указатель на полиморфный тип. Полиморфный тип тип класса, который содержит виртуальные функции (прямо или косвенно) Очевидно, что свойство быть полиморфным — это свойство типа во время компиляции.

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

4

Другие решения

Фактически Стандарт (C ++ 11) использует термин полиморфный тип класса, скорее, чем полиморфный тип когда он описывает поведение typeid:

Во-первых, здесь описывается, что происходит, когда typeid применяется к lvalue типа class (т.е. когда он делает то, что вы ожидаете):

(§5.2.8 / 2) Когда typeid применяется к выражению glvalue, тип которого является полиморфным типом класса (10.3), результат относится к std::type_info объект, представляющий тип наиболее производного объекта (1.8) (то есть динамического типа), на который ссылается glvalue. […]

Но когда вы применяете его к указателю (т.е. не к lvalue типа class), применяется правило ниже:

(§5.2.8 / 3) Когда typeid применяется к выражению, отличному от glvalue типа полиморфного класса, результат относится к std::type_info объект, представляющий статический тип выражения. […]

Он говорит, что вы получаете статический (не динамический) тип, то есть вы получаете объявленный тип указателя, а не тип объекта, на который он фактически указывает.

Итак, да, у указателей есть полиморфные характеристики, как вы описываете, но не когда дело доходит до результата typeid,

(На самом деле, все их полиморфные характеристики (включая, в частности, вызовы полиморфных функций-членов) проявляются только при явном разыменовании, используя * или используя ->, вовлечен. Таким образом, вы действительно должны сказать, что сами указатели не являются полиморфными; только объекты, которые вы получаете, когда разыменовываете их.)

9

По вопросам рекламы [email protected]