Приведение вниз

редактировать

В программировании на основе классов, понижающее преобразование или уточнение типа - это действие приведения ссылки базового класса к одному из его производных классов.

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

Другими словами, когда переменная базового класса (родительский класс ) имеет значение производного класса (дочерний класс ), возможно понижающее преобразование.

Содержание
  • 1 Примеры
    • 1.1 Java
    • 1.2 C ++
  • 2 Использование
  • 3 Критика
  • 4 См. Также
  • 5 Ссылки
  • 6 Внешние ссылки
Примеры

Java

public class Fruit {} // родительский класс public class Apple extends Fruit {} // дочерний класс public static void main (String args) {// Следующее является неявным восходящим преобразованием: родительский объект Fruit = новый Apple (); // Следующее - подавленное. Здесь это работает, поскольку переменная `parent` // содержит экземпляр Apple: Apple child = (Apple) parent; }

C ++

// Родительский класс: class Fruit {public: // Должен быть полиморфным для использования динамического приведения, проверенного во время выполнения. виртуальный ~ Fruit () = по умолчанию; }; // Дочерний класс: class Apple: public Fruit {}; int main (int argc, const char ** argv) {// Следующее - неявное преобразование вверх: Fruit * parent = new Apple (); // Следующее - подавленное. Здесь это работает, поскольку переменная `parent` // содержит экземпляр Apple: Apple * child = dynamic_cast (parent); удалить родителя; }
Использует

Понижающее преобразование полезно, когда тип значения, на которое ссылается родительская переменная, известен и часто используется при передаче значения в качестве параметра. В приведенном ниже примере метод objectToString принимает параметр Object, который, как предполагается, имеет тип String.

public static String objectToString (Object myObject) {// Это будет работать, только когда myObject, в настоящее время хранящее значение, является строкой. return (String) myObject; } public static void main (String args) {// Это будет работать, поскольку мы передали String, поэтому myObject имеет значение String. String result = objectToString («Моя строка»); Объект iFail = новый объект (); // Это не удастся, так как мы передали Object, который не имеет значения String. результат = objectToString (iFail); }

В этом подходе понижающее приведение не позволяет компилятору обнаружить возможную ошибку и вместо этого вызывает ошибку времени выполнения. Преобразование myObject в String ('(String) myObject') было невозможно во время компиляции, потому что бывают случаи, когда myObject имеет тип String, поэтому только во время выполнения мы можем выяснить, является ли переданный параметр логичным. Хотя мы также могли преобразовать myObject в строку времени компиляции, используя универсальный java.lang.Object.toString (), это может вызвать риск вызова реализации toString () по умолчанию, если она бесполезна или небезопасна, а обработка исключений не может предотвратить это..

В C ++ проверка типов во время выполнения реализована через dynamic_cast. Понижающее преобразование во время компиляции реализуется с помощью static_cast, но эта операция не выполняет проверку типа. Если он используется неправильно, это может привести к неопределенному поведению.

Критика

Некоторые языки, такие как OCaml, вообще запрещают понижающее преобразование.

Популярным примером плохо продуманного дизайна являются контейнеры верхние типы, такие как контейнеры Java до появления универсальных шаблонов Java, которые требуют понижающего преобразования содержащихся объектов, чтобы их можно было использовать снова.

См. Также
Ссылки
Внешние ссылки
Последняя правка сделана 2021-05-18 14:43:11
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте