C++ - Mám použít ukazatel nebo referenci ?

C++ dodává do jazyka nový odvozený typ - referenční proměnnou. "Odkaz" je jméno pro předem definované proměnné, které funguje jako druhé jméno (alias). Hlavní užitek odkazu je jeho použití jako formálního parametru ve funkci. Při použití odkazu jako parametru pracuje funkce s původními daty namísto s kopií. Odkazy poskytují vhodnou alternativu k ukazatelům na zpracování velkých struktur pomocí funkcí a jsou zásadní při návrhu tříd.
V tomto pohledu na dvě na první pohled stejné vlastnosti jazyka C/C++ si ukážeme použití a hlavní rozdíly ukazatele a reference.

Ukazatel na proměnou

int n = 10;
int *p_n;
*p_n = &n;

nebo

int *p_n = new int; //kompilátor alokuje 4 bajty prázdného paměťového prostoru
*p_n = 10;

Pokud použijeme *p_n = 20 změníme tím v prvním případě i proměnou n na 20 (p_n ukazuje na blok paměti kde je uložena proměná n typu int)

Referenční proměná

int n = 10;
int & r_n = n;

tzn. r_n je referenční proměnou (odkazem) k proměnné n. Z tohoto hlediska vypadá reference dost jako ukazatel v přestrojení, ve kterém se implicitně rozumí dereferenční operátor *. Ale mezi oběma zápisy existují rozdíly. Pro druhé (reference) je nezbytné odkaz inicializovat, když ho deklarujete. Nemůžete ho deklarovat a později mu přiřadit hodnotu, což je způsob, který můžete použít pro ukazatel.
Tedy

int n = 10;
int & r_n;
r_n = n;

nelze použít.

! Proměnnou typu reference byste měli inicializovat, když ji deklarujete.

Ukazatel a reference na datový objekt (struktura,třída)

struct zbozi
{
int id;
char nazev[30];

};
//definice struktury

zbozi ether = {0,"3Com Etherlink"};
zbozi *p_zbozi = ether;
// ukazatel ("ether" je adresou v paměti kde se nachází hodnota proměnné)
zbozi *p_zbozi2 = new zbozi;// další ukazatel
zbozi & r_zbozi = ether;
// reference na strukturu

a pak můžeme volat a přiřazovat hodnoty takto:

(*p_zbozi).id = 2;
p_zbozi->id = 2;
r_zbozi.id =2;


Funkce a ukazatele

include <iostream.h>

struct zbozi
{
char nazev[50];
int cena;
};

void vlozzbozi(zbozi * pzb);
void vypiszbozi(zbozi * pzb);

void main ()
{
zbozi ether;
vlozzbozi(&ether);
vypiszbozi(&ether);
}

void vlozzbozi(zbozi * pzb)
{
cout << "\nZadej nazev noveho zbozi:";
cin.getline(pzb->nazev,50);
cout << "\nZadej cenu noveho zbozi:";
cin >> pzb->cena;
}

void vypiszbozi(zbozi * pzb)
{
cout << "\nAdresa pameti\tZbozi\tCena\n";
cout << pzb << "\t" << pzb->nazev << "\t" << pzb->cena << "\n";
}

Funkce a reference

Nejčastěji se odkazy používají jako funkční parametry, vytvářejí ze jména proměnné ve funkci alias pro proměnnou ve volajícím programu. Tento postup předávání parametrů se nazývá předávání odkazem.

#include <iostream.h>

struct zbozi
{
char nazev[50];
int cena;
};

void vlozzbozi(zbozi & rzb);
void vypiszbozi(zbozi & rzb);

void main ()
{
zbozi ether;
vlozzbozi(ether);
vypiszbozi(ether);
}

void vlozzbozi(zbozi & rzb)
{
cout << "\nZadej nazev noveho zbozi:";
cin.getline(rzb.nazev,50);
cout << "\nZadej cenu noveho zbozi:";
cin >> rzb.cena;
}

void vypiszbozi(zbozi & rzb)
{
cout << "\nAdresa pameti\tZbozi\tCena\n";
cout << &rzb << "\t" << rzb.nazev << "\t" << rzb.cena << "\n";
}

Uvedený příklad ukazuje použití ukazatelů a referencí a to v obou případech ve funkci s parametrem předávaným odkazem.

Autor: Roman Pěch
Vytvořeno: 20.07.2002
Oblast: Programování