Jump to content

Непрозрачный указатель

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

Непрозрачные указатели присутствуют в нескольких языках программирования , включая Ada , C , C++ , D и Modula-2 .

Если язык строго типизирован , программы и процедуры , которые не имеют другой информации о непрозрачном указателе типа T, все равно могут объявлять переменные , массивы и поля записи типа T , присваивать значения этого типа и сравнивать эти значения на равенство. Однако они не смогут отменить ссылку на такой указатель и смогут изменить содержимое объекта только путем вызова какой-либо процедуры, содержащей недостающую информацию.

Непрозрачные указатели — это способ скрыть детали реализации интерфейса от обычных клиентов , чтобы реализацию можно было изменить без необходимости перекомпиляции использующих ее модулей . Это также приносит пользу программисту, поскольку можно создать простой интерфейс, а большую часть деталей можно скрыть в другом файле. [1] Это важно для обеспечения совместимости двоичного кода через разные версии общей библиотеки , например, .

Этот метод описан в разделе «Шаблоны проектирования» как шаблон «Мост» . Иногда его называют « дескрипторов классами ». [2] идиома « Pimpl » (от «указатель на идиому реализации»), [3] " Идиома брандмауэра компилятора ", [4] « D-указатель» или « Чеширский кот », особенно среди сообщества C++. [2]

Примеры [ править ]

Есть [ править ]

package Library_Interface is

   type Handle is limited private;

   -- Operations...

private
   type Hidden_Implementation;    -- Defined in the package body
   type Handle is access Hidden_Implementation;
end Library_Interface;

Тип Handle является непрозрачным указателем на реальную реализацию, которая не определена в спецификации. Обратите внимание, что тип является не только закрытым (чтобы запретить клиентам обращаться к типу напрямую и только посредством операций), но и ограниченным (чтобы избежать копирования структуры данных и, таким образом, предотвратить висячие ссылки).

package body Library_Interface is

   type Hidden_Implementation is record
      ...    -- The actual implementation can be anything
   end record;

   -- Definition of the operations...

end Library_Interface;

Эти типы иногда называют « типами Тафта » — в честь Такера Тафта , главного разработчика Ады 95, — потому что они были введены в так называемой поправке Тафта к Аде 83. [5]

С [ править ]

/* obj.h */

struct obj;

/*
 * The compiler considers struct obj an incomplete type. Incomplete types
 * can be used in declarations.
 */

size_t obj_size(void);

void obj_setid(struct obj *, int);

int obj_getid(struct obj *);
/* obj.c */

#include "obj.h"

struct obj {
    int id;
};

/*
 * The caller will handle allocation.
 * Provide the required information only
 */

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, но такие проверки выше для краткости опущены.

С++ [ править ]

/* PublicClass.h */

#include <memory>

class PublicClass {
 public:
  PublicClass();                               // Constructor
  PublicClass(const PublicClass&);             // Copy constructor
  PublicClass(PublicClass&&);                  // Move constructor
  PublicClass& operator=(const PublicClass&);  // Copy assignment operator
  PublicClass& operator=(PublicClass&&);       // Move assignment operator
  ~PublicClass();                              // Destructor

  // Other operations...

 private:
  struct CheshireCat;                   // Not defined here
  std::unique_ptr<CheshireCat> d_ptr_;  // Opaque pointer
};
/* PublicClass.cpp */

#include "PublicClass.h"

struct PublicClass::CheshireCat {
  int a;
  int b;
};

PublicClass::PublicClass()
    : d_ptr_(std::make_unique<CheshireCat>()) {
  // Do nothing.
}

PublicClass::PublicClass(const PublicClass& other)
    : d_ptr_(std::make_unique<CheshireCat>(*other.d_ptr_)) {
  // Do nothing.
}

PublicClass::PublicClass(PublicClass&& other) = default;

PublicClass& PublicClass::operator=(const PublicClass &other) {
  *d_ptr_ = *other.d_ptr_;
  return *this;
}

PublicClass& PublicClass::operator=(PublicClass&&) = default;

PublicClass::~PublicClass() = default;

Шаблон 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 г.). «Сделать прыщ проще» . Журнал доктора Добба . Проверено 7 мая 2008 г.
  4. ^ Херб Саттер. Радость прыщей (или еще об идиоме «компилятор-брандмауэр»)
  5. ^ Роберт А. Дафф (29 июля 2002 г.). «Re: Еще раз как его зовут?» . Группа новостей : comp.lang.ada . Проверено 11 октября 2007 г.
  6. ^ Использование d-указателя — почему и как KDE реализует непрозрачные указатели.
  7. ^ «Д-указатель» . Qt вики . Проверено 23 декабря 2016 г.

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

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: ea6044ba4b2577e5877785d20ccfc3f7__1680669360
URL1:https://arc.ask3.ru/arc/aa/ea/f7/ea6044ba4b2577e5877785d20ccfc3f7.html
Заголовок, (Title) документа по адресу, URL1:
Opaque pointer - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)