pondělí 29. listopadu 2010

Přetěžování operátorů

Nejprve malý teoretický úvod do C++, zejména přetěžování funkcí a operátorů.
Přetěžování funkcí je vlastně strašně jednoduchá myšlenka. Lze nadefinovat více funkcí se stejným jménem. Tyto funkce však musí mít různé parametry. To proto, aby šlo rozlišit, která varianta je v tom daném místě myšlena.
Operátory jsou speciální funkce, které se můžou volat klasicky jako funkce, ale můžou se volat i trochu jiným způsobem. Napíšu-li například výraz
a = b + c

znamená to následující volání funkcí:
a.operator=(operator+(b, c))

Zavolá se tedy nejdříve funkce s názvem operator+ s parametry b a c a na výsledek se zavolá funkce objektu a, která se jmenuje operator=.
Tyto operátory se z programátorského hlediska chovají jako běžné funkce. Lze je tedy například přetěžovat.

Zrovna programuji vlastní knihovní třídy pro práci s daty. Předpoklad je, že celkový objem dat potřebný pro práci programu bude řádově desítky megabajtů.
K datům potřebuji přistupovat dvojím způsobem. Někdy potřebuji náhodný přístup, tedy vyhledat v datech jednu konkrétní položku. Někdy zase potřebuji sekvenční přístup, tedy sekvenčně projít všechny položky.
K prvnímu způsobu jsem zvolil speciální funkci, jmenující se operator[]. Tento operátor je používán stejným způsobem, jako hranaté závorky u polí. Dalo by se říci, že jediným rozumným parametrem tohoto operátoru je celé číslo. Ale vemte si třeba PHP a jeho asociativní pole. To bere jako parametr operátoru [] i string. Já jsem v tomto případě vzal operator[], který vrací odkaz dovnitř své datové struktury přetypovaný na void* a jako parametr bere proměnnou typu void*. V této variantě operátor hledá ve své datové struktuře prvek, který je rovný zadanému parametru. (Jak se pozná, že prvek je rovný parametru není obsahem tohoto blogpostu, prozradím jen, že je k tomu potřeba definovat speciální funkci.)
Druhý způsob je přesně práce pro tzv. iterátory. Vytvořil jsem tedy novou třídu implementující iterátor nad danou knihovní třídou pracující s daty. Tento iterátor by se měl chovat nějakým rozumným způsobem: mělo by být možné jej posunout o určitý počet prvků vpřed nebo vzad, porovnat jej s jiným iterátorem nebo přistoupit na hodnotu, na kterou ukazuje. Není nic jednoduššího, než toto implementovat toto pomocí operátorů. Pak lze jednoduše napsat
if(it1 == it2){ ... }

nebo
it1++
.

1 komentář:

  1. no panečku, pěkně si se rozjel ... Někdy bych si rád prohlédl zdrojový kód :-)

    OdpovědětVymazat