Непрозрачный указатель
В компьютерном программировании непрозрачный указатель — это особый случай непрозрачного типа данных , типа данных, объявленного указателем на запись или структуру данных некоторого неопределенного типа.
Непрозрачные указатели присутствуют в нескольких языках программирования , включая 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 библиотеки .
См. также [ править ]
Ссылки [ править ]
- ^ Крис МакКиллоп. «Инструменты программирования — непрозрачные указатели» . Программные системы QNX . Проверено 16 января 2019 г.
- ↑ Перейти обратно: Перейти обратно: а б Брюс Экель (2000). «Глава 5: Сокрытие реализации» . Мышление на C++, Том 1: Введение в стандарт C++ (2-е изд.). Прентис Холл. ISBN 0-13-979809-9 .
- ^ Владимир Батов (25 января 2008 г.). «Сделать прыщ проще» . Журнал доктора Добба . Проверено 7 мая 2008 г.
- ^ Херб Саттер. Радость прыщей (или еще об идиоме «компилятор-брандмауэр»)
- ^ Роберт А. Дафф (29 июля 2002 г.). «Re: Еще раз как его зовут?» . Группа новостей : comp.lang.ada . Проверено 11 октября 2007 г.
- ^ Использование d-указателя — почему и как KDE реализует непрозрачные указатели.
- ^ «Д-указатель» . Qt вики . Проверено 23 декабря 2016 г.
Внешние ссылки [ править ]


- Идиома «Пимпл»
- Брандмауэры компиляции или брандмауэры компиляции
- Идиома быстрого прыща
- D-указатели — KDE TechBase
- Когда вы выполняете «XOR» указателя со случайным числом» [1] [2] , результатом является «действительно непрозрачный» указатель [3] .
- Сделать прыщи проще , Владимир Батов