В компьютерном программировании , непрозрачным указатель представляет собой частный случай из непрозрачного типа данных , A типа данных объявлен указатель на рекордно или структуру данных некоторых неопределенного типа.
Непрозрачные указатели присутствуют в нескольких языках программирования, включая Ada , C , C ++ , D и Modula-2 .
Если язык строго типизирован , программы и процедуры , которые не имеют другой информации о типе непрозрачного указателя T, могут по-прежнему объявлять переменные , массивы и поля записи типа T , присваивать значения этого типа и сравнивать эти значения на равенство. Однако они не смогут отменить ссылку на такой указатель и могут только изменить содержимое объекта, вызвав некоторую процедуру, имеющую недостающую информацию.
Непрозрачные указатели способ скрыть реализации деталей с интерфейсом от обычных клиентов, так что реализация может быть изменена без необходимости перекомпилировать модули , используя его. Это также приносит пользу программисту, поскольку может быть создан простой интерфейс, а большая часть деталей может быть скрыта в другом файле. [1] Это важно для обеспечения совместимости двоичного кода, например, с помощью различных версий разделяемой библиотеки .
Этот метод описан в шаблонах проектирования как шаблон «Мост» . Его иногда называют « классами дескрипторов », [2] « идиомой Pimpl » (для «указателя на идиому реализации»), [3] « идиомой брандмауэра компилятора », [4] « d-указателем» или « чеширским котом». ", особенно среди сообщества C ++. [2]
Примеры [ править ]
Ада [ править ]
Пакет Library_Interface является Тип ручка имеет ограниченный частную ; - Операции ...закрытый тип Hidden_Implementation ; - В теле пакета определен тип Handle - это доступ Hidden_Implementation ; конец Library_Interface ;
Тип Handle
представляет собой непрозрачный указатель на реальную реализацию, которая не определена в спецификации. Обратите внимание, что тип является не только частным (чтобы запретить клиентам доступ к типу напрямую и только через операции), но также и ограниченным (чтобы избежать копирования структуры данных и, таким образом, предотвратить висячие ссылки).
пакет тела Library_Interface является тип Hidden_Implementation - это запись ... - Фактической реализацией может быть что угодно, конец записи ; - Определение операций ...конец Library_Interface ;
Эти типы иногда называют « типами Тафта » - по имени Такера Тафта , главного разработчика Ada 95 - потому что они были введены в так называемой поправке Тафта к Ada 83. [5]
C [ править ]
/ * obj.h * /struct obj ;/ * * Компилятор считает struct obj неполным типом. В объявлениях можно использовать неполные типы *. * /size_t obj_size ( недействительно );void obj_setid ( struct obj * , int );int obj_getid ( struct obj * );
/ * obj.c * /#include "obj.h"struct obj { int id ; };/ * * Вызывающий обработает выделение. * Укажите только необходимую информацию * /size_t obj_size ( void ) { return sizeof ( struct obj ); }void obj_setid ( struct obj * o , int i ) { o -> id = i ; }int obj_getid ( struct obj * o ) { return o -> id ; }
Этот пример демонстрирует способ достижения аспекта сокрытия информации ( инкапсуляции ) объектно-ориентированного программирования с использованием языка C. Если бы кто-то захотел изменить определение struct obj
, не было бы необходимости перекомпилировать любые другие модули в программе, которые используют obj.h
файл заголовка, если API также не был изменен. Обратите внимание, что может быть желательно, чтобы функции проверяли, что переданный указатель не является указателем NULL
, но такие проверки были опущены выше для краткости.
C ++ [ править ]
/ * PublicClass.h * /#include <память>класс PublicClass { общедоступный : PublicClass (); // Конструктор PublicClass ( const PublicClass & ); // Копируем конструктор PublicClass ( PublicClass && ); // Перемещение конструктора PublicClass & operator = ( const PublicClass & ); // Копировать оператор присваивания PublicClass & operator = ( PublicClass && ); // Переместить оператор присваивания ~ PublicClass (); // Деструктор // Прочие операции ... частный : struct CheshireCat ; // Здесь не определено std :: unique_ptr < CheshireCat > d_ptr_ ; // Непрозрачный указатель };
/ * PublicClass.cpp * /#include "PublicClass.h"struct PublicClass :: CheshireCat { int a ; int b ; };PublicClass :: PublicClass () : d_ptr_ ( std :: make_unique < CheshireCat > ()) { // Ничего не делать. }PublicClass :: PublicClass ( const PublicClass & other ) : d_ptr_ ( std :: make_unique < CheshireCat > ( * other . D_ptr_ )) { // Ничего не делать. }PublicClass :: PublicClass ( PublicClass && другой ) = по умолчанию ;PublicClass и PublicClass :: operator = ( const PublicClass и другие ) { * d_ptr_ = * другое . d_ptr_ ; return * this ; }PublicClass и PublicClass :: operator = ( PublicClass && ) = по умолчанию ;PublicClass :: ~ PublicClass () = по умолчанию ;
Шаблон d-указателя - одна из реализаций непрозрачного указателя . Он обычно используется в классах C ++ из-за своих преимуществ (отмеченных ниже). D-указатель - это частный член данных класса, указывающий на экземпляр структуры. Этот метод позволяет объявлениям классов опускать частные данные-члены, за исключением самого d-указателя. [6] В результате
- большая часть реализации класса скрыта
- добавление новых элементов данных в частную структуру не влияет на двоичную совместимость
- файл заголовка, содержащий объявление класса, должен включать только те файлы, которые необходимы для интерфейса класса, а не для его реализации.
Одним из побочных преимуществ является то, что компиляция выполняется быстрее, потому что файл заголовка изменяется реже. Обратите внимание, что возможным недостатком шаблона d-указателя является косвенный доступ к члену через указатель (например, указатель на объект в динамическом хранилище), который иногда медленнее, чем доступ к простому члену без указателя. D-указатель активно используется в библиотеках Qt [7] и KDE .
См. Также [ править ]
- Бинарный интерфейс приложения
- Ручка (вычисление)
- Идиома программирования
- Шаблон данных частного класса
Ссылки [ править ]
- ^ Крис Маккиллоп. «Инструменты программирования - непрозрачные указатели» . Программные системы QNX . Проверено 16 января 2019 .
- ^ а б Брюс Экель (2000). «Глава 5: Скрытие реализации» . Мышление на C ++, Том 1: Введение в стандартный C ++ (2-е изд.). Прентис Холл. ISBN 0-13-979809-9.
- ↑ Владимир Батов (25 января 2008 г.). "Делаем Pimpl проще" . Журнал доктора Добба . Проверено 7 мая 2008 .
- ^ Херб Саттер. Радость сутенеров (или еще об идиоме компилятор-брандмауэр)
- ^ Роберт А. Дафф (2002-07-29). "Re: Как его снова зовут?" . Группа новостей : comp.lang.ada . Проверено 11 октября 2007 .
- ^ Использование d-указателя - Почему и как KDE реализует непрозрачные указатели
- ^ "D-указатель" . Qt wiki . Дата обращения 23 декабря 2016 .
Внешние ссылки [ править ]
В Wikibook Ada Programming есть страница по теме: Типы Taft |
- Идиома Pimpl
- Межсетевые экраны компиляции
- Идиома Fast Pimpl
- D-указатели - KDE TechBase
- Когда вы выполняете «XOR указателя со случайным числом» [1] [2] , результатом является «действительно непрозрачный» указатель [3] .
- Делаем Pimpl Easy , Владимир Батов