Ve všech vědách existují standardní notace, které usnadňují pochopení myšlenek. Například v matematice je násobení, dělení, sčítání a další symbolická notace. Výraz (x + y * z) je mnohem snazší pochopit než "násobit y, z a přidat do x". Představte si, že až do XVI. Století matematika neměla symbolickou notaci, všechny výrazy byly psány slovně, jako by to byl umělecký text s popisem. A obvyklé známky operací pro nás se objevily později. Je obtížné přeceňovat význam krátkého záznamu. Na základě těchto úvah byly programovací jazyky přidány k přetížení operátorů. Zvažte příklad.
Příklad přetížení operátorů
//si představte komplexní číslo ve formě dvojice čísel splovoucí bod.
třída komplex {{12} double re, im;
veřejný:
komplex (dvojitý r, dvojitý i): re (r), im (i) {} //konstruktor
komplexní operátor + (komplex); //komplexní operátor * (komplex); //přetížení násobení
};
void main () {
komplexní {1 2}, b {3}}, c {0}};
c = a + b;
c = operátor + (b); ////funkce operátora může být nazývána libovolná funkce, tato položka je ekvivalentní k + b
c = a * b + komplexu (1 3); //provádí obvyklá pravidla prioritních operací sčítání a násobení
}
Stejně tak lze provést, jako je například operátor přetížení /O v jazyce C ++ a přizpůsobit je pro zobrazení takové složité struktury jako šablony.
Provozovatelé k dispozici pro přetížení
Úplný seznam všech provozovatelů, pro které lze použít přetížení:
nový []
+ | - | * | / | % | ^ | |
~ | ! | = | /p> | > | + = | |
- = | * = | /= | % = | ^ = | and = | | = |
= | = | == | ! = | |||
> = | | | ++ | - | - & gt; * | , | |
-> | vymazat |
Jak je patrné z tabulky, přetížení je přípustné pro většinu operátorů jazyků. Není třeba přetížit obsluhu. To se provádí pouze pro pohodlí. Proto chybí například přetížení operátorů v Javě. A teď o tak důležitém okamžiku.
Provozovatelé, jejichž přetížení je zakázáno
- Povolení k viditelnosti - «::»;
- Volba člena je ".";
- Výběr člena pomocí ukazatele na člena - ". *";
- Třetí podmíněný operátor - «?:»;
- velikost operátora;
- Typový operátor.
Správným operantem dat operátorů je název, ne hodnota. Povolení jejich přetížení by proto mohlo vést k mnoha nejednoznačným návrhům a značně by komplikovalo životy programátorů. Přestože existuje mnoho programovacích jazyků, které umožňují přetížení všech operátorů - například přetížení operátorů Pythonu.
Omezení operátor přetížení
- Nemůžete změnit binární operátor na unary a naopak, protože nemůžete přidat třetí operand.
- Nemůžete vytvořit jiné operátory než ty, které jsou. Toto omezenípodporuje odstranění mnoha nejednoznačností. Pokud je potřeba nový operátor, můžete použít funkci, která pro tyto účely provede požadovanou akci.
- Funkce operátora může být buď členem třídy, nebo má alespoň jeden typový argument. Výjimkou jsou noví operátoři a operátoři mazání. Toto pravidlo zakazuje změnu významu výrazů, pokud neobsahují uživatelem definované typy objektů. Zejména nelze vytvořit funkci operátora, která by fungovala pouze s ukazateli nebo nucena operátora doplňku pracovat jako násobení. Výjimkou jsou operátoři "=", "& amp;" a "," pro objekty třídy.
- Funkce operátora s prvním termínem, který patří k jednomu z vestavěných typů dat v jazyce C ++, nemůže být členem třídy.
- Název každé funkce operátora začíná operátorem klíčového slova, po němž následuje symbolické označení samotného operátora.
- Vestavěné operátory jsou definovány tak, že mezi nimi existuje spojení. Následující operátory jsou například vzájemně ekvivalentní: ++ x; x + = 1; x = x + 1. Po nové definici se spojení mezi nimi nezachová. O zachování své práce společně s novými typy programátorů se budou muset postarat o sebe.
- Kompilátor nemůže myslet. Výrazy z + 5 a 5 + z (kde z - komplexní číslo) bude překladačem zvažováno různými způsoby. První je "komplexní + číslo" a druhé je "číslo + složité". Proto pro každý výraz potřebujete definovat vlastní prohlášení o přidání.
- Když hledá definici operátora, překladač nedává přednost žádným členům třídy, ani pomocným funkcím,které jsou definovány mimo třídu. Pro překladatele jsou stejné.
Interpretace binárních a unárních operátorů.
binární operátor je definován jako člen funkce jedné proměnné nebo funkce dvou proměnných. Pro každý binární vyjádření obsluhy @ s @ b @ jen struktur:
teplotě nižší než script type = "text /javascript" & gt;
var blockSettings3 = {blockId: "R-A-70350-3", renderTo "yandex_rtb_R-A-70350-3", async :! 0};
, pokud (document.cookie.indexOf ("abmatch =") větší nebo rovno 0) {
blockSettings3 = {blockId: "RA-70350-3", renderTo „yandex_rtb_R-A-70350- 3 ", statId: 70350async:! 0};
}
! Funkce (a, b, c, d, e) {a [c] = a [c] || [], se [C] .push (funkce () {Ya .Context.AdvManager.render (blockSettings3)}), e = b.getElementsByTagName ("scénář") , d = b.createElement ("scénář"), d.type = "text /javascript", d.src = "//an.yandex.ru/system/context.js",d.async=!0e.parentNode.insertBefore(d,e)}(this,this.document,"yandexContextAsyncCallbacks");
a.operátor @ (b) nebo operátor @ (a, b).
Zvažte příklad třídy komplexních čísel pro definici operací jako členů třídy a pomocných.
třída komplex {{174} double re, im;
veřejnost:
komplexní & operátor + = (komplex z);
komplexní & operátor * = (komplex z);
};
//pomocné funkce
komplexní operátor + (komplex z1 komplex z2);
komplex operátor + (komplex z, dvojitý a);
, které operátory bude vybrán a být volen obecně určen vnitřních mechanismů jazyka, které budou popsány níže. Obvykle se to děje podle typů.
Vyberte popsat funkci jako člen třídy nebo mimo ni - je, obecně, chuť. Ve výše uvedeném příkladu je princip výběru byla následující: v případě, že operace změní levý operand (například A + = b), a pak jej zaznamenat ve třídě a pomocí měnitelným převodem při, pro jeho bezprostřední změny; pokud operace není nicmodifikuje a jednoduše vrací novou hodnotu (například a + b) - za definici třídy.
Definice unarnыh operátoři přetížení v C ++ děje stejným způsobem, s tím rozdílem, že se dělí na dva typy:
- operátor prefixu, umístěný na operandu, - @a, například i ++. o Definováno jako a.operátor @ () nebo operátor @ (aa);
- operátor postfixu, umístěný za operandem, - b @, například i ++. o definováno jako b.operator @ (int) nebo operátor @ (b, int)
Stejným způsobem jako pro binární operátory, když reklama je operátor ve třídě a výběru mimo třída mechanismy budou realizovány C ++.
Pravidla výběru operátora
Nechť binární operátor @ x je aplikován na objektech třídy X a třídy Y. y pravidel pro umožnění X- Y bude následující:
- je-li X třídou, v něm hledá definici operátora @ jako výraz X nebo základní třídu X;
- pro zobrazení kontextu, ve kterém je umístěn výraz x @ y;
- pokud X patří do jmenného prostoru N, vyhledejte příkaz operátora N;
- Pokud Y patří do jmenného prostoru M, vyhledejte příkaz operátora M.
Pokud bylo nalezeno několik prohlášení provozovatele operátora @ v 1-4, volba bude provedena podle pravidel povolení přeplněných funkcí.
Hledání jednorázových operátorů probíhá přesně stejným způsobem.
Upřesnit definici komplexu třídy
Nyní budeme sestavit třídu komplexních čísel podrobnějiprokázat řadu dříve oznámených pravidel.
třídový komplex {
double re, im;
veřejnost:
komplexní & operátor + = (komplex z) {//pracuje s výrazy formuláře z1 + = z2
re + = z.re;
im + = z.im;
vrátí * toto;
}
komplexní & operátor + = (double a) {//pracuje s výrazy formuláře z1 + = 5;
re + = a;
vrátit * toto;
}
komplex (): re , im
{} //konstruktor pro implicitní inicializaci. Takže všechna deklarovaná celočíselná čísla budou mít počáteční hodnoty (0 0)
složité (dvojité r): re (r), im
{} //konstruktor činí vyjádření formy komplexu z = 11 možné; ekvivalentní záznamu z = komplex
;
komplex (dvojitý r, dvojitý i): re (r), im (i) {} //konstruktor
};
komplexní operátor + (komplex z1 komplex z2) {//pracuje s výrazy formu z1 + z2
komplex res = z1;
návrat res + = z2; //používá operátor definovaný jako členská funkce
}
komplexní operátor + (komplex z, dvojitý a) {//zpracovává výrazy formuláře z + 2
komplex res = z;
návrat res + = a;
}
komplexní operátor + (dvojité a, komplex z) {//zpracovává výrazy formuláře 7 + z
komplex res = z;
návrat res + = a;
}
//
Jak lze vidět z kódu, přetížení operátorů má poměrně komplikovaný mechanismus, který může výrazně růst. Takový podrobný přístup však umožňuje přetížení i pro velmi složité datové struktury. Například přetížení operátorů C ++ ve třídě šablon. Takové vytváření funkcí pro každého a vše může být zdlouhavé a vést k chybám. Například pokud přidáte třetí typ zvažovaných funkcí, budete muset zvážit operace z důvodů kombinace tří typů. Budeme muset napsat 3 funkce s jedním argumentem, 9 - s dvěma a 27 - se třemi. Proto, v některých případech, provádění všech těchto funkcí a jejich významné sníženímnožství lze dosáhnout použitím konverze typů.
;
komplex (dvojitý r, dvojitý i): re (r), im (i) {} //konstruktor
};
komplexní operátor + (komplex z1 komplex z2) {//pracuje s výrazy formu z1 + z2
komplex res = z1;
návrat res + = z2; //používá operátor definovaný jako členská funkce
}
komplexní operátor + (komplex z, dvojitý a) {//zpracovává výrazy formuláře z + 2
komplex res = z;
návrat res + = a;
}
komplexní operátor + (dvojité a, komplex z) {//zpracovává výrazy formuláře 7 + z
komplex res = z;
návrat res + = a;
}
//