Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

В компьютерном программировании , непрозрачным указатель представляет собой частный случай из непрозрачного типа данных , 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 .

См. Также [ править ]

  • Бинарный интерфейс приложения
  • Ручка (вычисление)
  • Идиома программирования
  • Шаблон данных частного класса

Ссылки [ править ]

  1. ^ Крис Маккиллоп. «Инструменты программирования - непрозрачные указатели» . Программные системы QNX . Проверено 16 января 2019 .
  2. ^ а б Брюс Экель (2000). «Глава 5: Скрытие реализации» . Мышление на C ++, Том 1: Введение в стандартный C ++ (2-е изд.). Прентис Холл. ISBN 0-13-979809-9.
  3. Владимир Батов (25 января 2008 г.). "Делаем Pimpl проще" . Журнал доктора Добба . Проверено 7 мая 2008 .
  4. ^ Херб Саттер. Радость сутенеров (или еще об идиоме компилятор-брандмауэр)
  5. ^ Роберт А. Дафф (2002-07-29). "Re: Как его снова зовут?" . Группа новостейcomp.lang.ada . Проверено 11 октября 2007 .
  6. ^ Использование d-указателя - Почему и как KDE реализует непрозрачные указатели
  7. ^ "D-указатель" . Qt wiki . Дата обращения 23 декабря 2016 .

Внешние ссылки [ править ]

  • Идиома Pimpl
  • Межсетевые экраны компиляции
  • Идиома Fast Pimpl
  • D-указатели - KDE TechBase
  • Когда вы выполняете «XOR указателя со случайным числом» [1] [2] , результатом является «действительно непрозрачный» указатель [3] .
  • Делаем Pimpl Easy , Владимир Батов