Punter opac
En programació informàtica, un punter opac és un cas especial d'un tipus de dades opac, un tipus de dades declarat com un punter a un registre o una estructura de dades d'algun tipus no especificat.
Els punters opacs estan presents en diversos llenguatges de programació, com ara Ada, C, C++, D i Modula-2.
Si el llenguatge està ben escrit, els programes i procediments que no tenen cap altra informació sobre un punter opac tipus T encara poden declarar variables, matrius i camps de registre de tipus T, assignar valors d'aquest tipus i comparar aquests valors per a la igualtat. Tanmateix, no podran desreferenciar aquest punter i només poden canviar el contingut de l'objecte cridant a algun procediment que tingui la informació que falta.
Els punters opacs són una manera d'ocultar els detalls d'implementació d'una interfície als clients normals, de manera que la implementació es pot canviar sense necessitat de recompilar els mòduls que la fan servir. Això també beneficia el programador, ja que es pot crear una interfície senzilla i la majoria dels detalls es poden amagar en un altre fitxer.[1] Això és important per proporcionar compatibilitat de codi binari a través de diferents versions d'una biblioteca compartida, per exemple.
Aquesta tècnica es descriu a Patrons de disseny com el patró Bridge. De vegades s'anomena " classes de maneig ",[2] el " idioma Pimpl " (per a "idioma del punter a la implementació"),[3] " idioma del tallafoc del compilador ",[4] " puntador d" o " Gat de Cheshire ". ", especialment entre la comunitat C++.[2]
Exemples
[modifica]C
[modifica]/* 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 *);
Aquest exemple mostra una manera d'aconseguir l'aspecte d'amagat d'informació (encapsulació) de la programació orientada a objectes mitjançant el llenguatge C. Si algú vol canviar la definició de struct obj
, seria innecessari recompilar qualsevol altre mòdul del programa que utilitzi el fitxer de capçalera obj.h
tret que també es canviés l'API. Cal tenir en compte que pot ser desitjable que les funcions comprovin que el punter passat no és NULL
, però aquestes comprovacions s'han omès anteriorment per concisió.
C++
[modifica]/* 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;
El patró de punter d és una de les implementacions del opaque pointer . S'utilitza habitualment a les classes C++ a causa dels seus avantatges (que s'indiquen a continuació). Un punter d és un membre de dades privades de la classe que apunta a una instància d'una estructura. Aquest mètode permet que les declaracions de classe ometin els membres de dades privades, excepte el punter d. Com a resultat,
- més de la implementació de la classe està oculta
- afegir nous membres de dades a l'estructura privada no afecta la compatibilitat binària
- el fitxer de capçalera que conté la declaració de classe només ha d'incloure els fitxers necessaris per a la interfície de classe, en lloc de per a la seva implementació.
Un avantatge secundari és que les compilacions són més ràpides perquè el fitxer de capçalera canvia amb menys freqüència. Tingueu en compte que el possible desavantatge del patró d-punter és l'accés indirecte als membres mitjançant el punter (per exemple, el punter a l'objecte en l'emmagatzematge dinàmic), que de vegades és més lent que l'accés a un membre senzill i no punter. El punter d s'utilitza molt a les biblioteques Qt [5] i KDE.
Referències
[modifica]- ↑ Chris McKillop. «Programming Tools — Opaque Pointers» (en anglès). QNX Software Systems. Arxivat de l'original el 2021-11-12. [Consulta: 16 gener 2019].
- ↑ 2,0 2,1 Bruce Eckel. «Chapter 5: Hiding the Implementation». A: Thinking in C++, Volume 1: Introduction to Standard C++ (en anglès). 2a edició. Prentice Hall, 2000. ISBN 0-13-979809-9.
- ↑ Vladimir Batov Dr. Dobb's Journal, 25-01-2008 [Consulta: 7 maig 2008].
- ↑ Herb Sutter. The Joy of Pimpls (or, More About the Compiler-Firewall Idiom)
- ↑ «D-Pointer» (en anglès). Qt wiki. [Consulta: 23 desembre 2016].