Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /home/www/novacisko.cz/subdomains/bredy/init.php on line 11

Warning: mysql_connect(): Headers and client library minor version mismatch. Headers:50562 Library:100020 in /home/www/novacisko.cz/subdomains/bredy/init.php on line 11

Warning: Cannot modify header information - headers already sent by (output started at /home/www/novacisko.cz/subdomains/bredy/init.php:11) in /home/www/novacisko.cz/subdomains/bredy/index.php on line 38
Šablony a kvalifikátor const - Jak správně konstruovat šablony s ukazatelem? - Bredyho blog - Ondřej Novák
Bredyho blog - Ondřej Novák

Šablony a kvalifikátor const - Jak správně konstruovat šablony s ukazatelem?

Chytrý ukazatel nebo pole? Vždy se jedná o šablonu, která obsahuje ukazatel na T. Přitom je třeba postihnout chování const


S kvalifikátorem const si lze občas užít dost legrace. Podívejme se, jaká past nás čeká při konstrukci šablony obsahující ukazatel na T. Nejprve příklad takové šablony

template<class T>
class PrikladSablony
{
T *ukazatel;

public:

PrikladSablony(T *p):ukazatel(p) {}
T *operator->() const {return ukazatel;}
T &operator *() const {return *ukazatel;}
};

Takto nadefinovaná šablona nejspíš vyhoří. Překladač nebude chtít vydat nekonstantní ukazatel ve funkci mající kvalifikátor const. Přitom se situace zdá logická, protože vydáním ukazatele a změnou dat v paměti kam ukazatel ukazuje se na vlastní instanci ukazatele nic nemění.

Běžné řešení této situace můžeme vidět v různých programech:

 T *operator->()  {return ukazatel;}
T &operator *() {return *ukazatel;}
const T *operator->() const {return ukazatel;}
const T &operator *() const {return *ukazatel;}

Tohle řešení funguje dobře, ale je jen částečné.

Všechny varianty ukazatele

Standardní ukazatel má celkem 4 varianty.

Objekt *ukazatel
Prostý ukazatel na objekt, lze libovolně měnit
const Object *ukazatel
Ukazatel na konstantní objekt. Lze změnit adresu ukazatele, nelze změnit objekt, na který ukazatel ukazuje.
Object const *ukazatel
Konstantní ukazatel na nekonstantní objekt. Lze měnit objekt, nelze měnit ukazatel
const Object const *ukazatel
Konstantní ukazatel na konstantní objekt. Nelze změnit nic.

Adekvátně by tedy měli existivat varianty pro náš PrikladSablony

PrikladSablony<Objekt> ukazatel
Prostý ukazatel na objekt, lze libovolně měnit
PrikladSablony<const Object> ukazatel
Ukazatel na konstantní objekt. Lze změnit adresu ukazatele, nelze změnit objekt, na který ukazatel ukazuje.
const PrikladSablony<Object> ukazatel
Konstantní ukazatel na nekonstantní objekt. Lze měnit objekt, nelze měnit ukazatel
const PrikladSablony<const Object> ukazatel
Konstantní ukazatel na konstantní objekt. Nelze změnit nic.

Řešení uvedné v předchozím oddíle však toto neumožňujeme.

PrikladSablony<Objekt> ukazatel
odpovídá Objekt *ukazatel
PrikladSablony<const Object> ukazatel
odpovídá const Objekt *ukazatel
const PrikladSablony<Object> ukazatel
odpovídá const Objekt *ukazatel
const PrikladSablony<const Object> ukazatel
odpovídá const const Objekt *ukazatel

Jak na to?

Řešení je jednoduché. Vraťme se k původní třídě, jenom ji lehce poupravíme:

template<class T>
class PrikladSablony
{
mutable T *ukazatel;

public:

PrikladSablony(T *p):ukazatel(p) {}
T *operator->() const {return ukazatel;}
T &operator *() const {return *ukazatel;}
};

Klíčové slovo mutable zajistí, že překladač umožní vydat ukazatel i případě, že metoda, která jej vrací je const a to bez ohledu na typ T. Navíc je toto řešení logické, protože jak jsme řekli, objekt ukazatele pouze spravuje ukazatel na T jako hodnotu, nikoliv jako objekt.

vytvořeno: 8.3.2007 10:10:23, změněno: 8.3.2007 10:10:23
Jsou informace v článku pro Vás užitečné?
  • (2)
  • (0)
  • (0)
  • (0)
  • (1)

Podobné články

Šablony: Být vládce kvalifikátorů

Kvalifikátory (to jsou klíčová slova const, mutable, volatile, atd) jsou důležitou součástí v C++. Často hodně pomůžou, často se jich nemůžeme zbavit. Jak je ovládnout?

Dědičnost šablon, CRTP a Invoker

OOP prvky lze používat i při generickém programování pomocí šablon. Dědit šablony je snadné, podívejme se i na polymorfické šablony.

Šablony: Nastavování vlastností tříd

Svět šablon v C++ je velmi zajímavý, pro znalce dokonalý, pro začátečníky šílený a nepřehledný. Následující článek pojednává o dalším kouzlu se šablonami

Jak dostat řetězec do parametru šablony

Současná norma C++ umožňuje jako parametr šablony použít tzv. integrální typy, tedy typy odvozené od int, dále bool, ukazatel a referenci. Ukažme si, existuje způsob, jak tam dostat i řetězec

Šablona jako parametr šablony

Traits a zajímavá technika o které se málo ví
Reklama: