call by reference (tsz. call by references)
A call-by-reference (referencia szerinti átadás) egy olyan módszer C++-ban, amely lehetővé teszi, hogy egy függvény egy változóra közvetlenül hivatkozzon ahelyett, hogy annak másolatát kapná meg. Ez hatékonyabb memóriahasználatot biztosít, és lehetővé teszi a változó értékének módosítását a függvényen belül.
A C++ kétféleképpen tud változókat függvényeknek átadni:
Átadás típusa | Magyarázat |
---|---|
Call-by-Value (Érték szerinti átadás) | A változó másolata kerül a függvénybe, az eredeti változó nem módosul. |
Call-by-Reference (Referencia szerinti átadás) | A függvény az eredeti változóra hivatkozik, így annak értéke módosulhat. |
Nézzünk egy példát, amikor érték szerint adunk át egy változót egy függvénynek:
#include <iostream>
using namespace std;
void novel(int x) { // Érték szerinti átadás
x += 10; // Csak a másolatot módosítjuk
}
int main() {
int szam = 5;
novel(szam); // Az eredeti változó nem változik
cout << "Eredeti ertek: " << szam << endl; // Kiírja: 5
return 0;
}
Kimenet:
Eredeti ertek: 5
Miért?
- Az x
változó egy másolat, így a novel()
függvényben történt változtatások nem hatnak a szam
változóra.
Most nézzük meg, hogyan használhatjuk a referencia szerinti átadást (&
operátorral):
#include <iostream>
using namespace std;
void novel(int& x) { // Referencia szerinti átadás
x += 10; // Az eredeti változót módosítjuk
}
int main() {
int szam = 5;
novel(szam); // Az eredeti változó módosul
cout << "Eredeti ertek: " << szam << endl; // Kiírja: 15
return 0;
}
Kimenet:
Eredeti ertek: 15
Mi történt?
- A novel(int& x)
függvényben a x
ugyanazt a memóriaterületet használja, mint az eredeti szam
változó.
- Így amikor x
értékét módosítjuk, a szam
változó értéke is módosul.
A C++ nem másolja le a tömböket függvényhíváskor, így azokat mindig referencia szerint adjuk át.
#include <iostream>
using namespace std;
void kiir(int tomb, int meret) { // A tömb automatikusan referenciaként kerül átadásra
for (int i = 0; i < meret; i++) {
tomb += 5; // Módosítjuk az eredeti tömböt
}
}
int main() {
int szamok = {1, 2, 3, 4, 5};
kiir(szamok, 5);
for (int i = 0; i < 5; i++) {
cout << szamok << " "; // Kiírja: 6 7 8 9 10
}
return 0;
}
Fontos:
- A tömb mindig referencia szerint kerül átadásra, így az kiir()
függvény módosítani tudja annak elemeit.
- Ha nem szeretnénk, hogy a függvény módosítsa az adatokat, használhatunk const
kulcsszót:
void kiir(const int tomb, int meret) { ... }
const
Ha egy változót referenciaként akarunk átadni egy függvénynek, de nem szeretnénk módosítani, akkor használhatjuk a const
kulcsszót.
#include <iostream>
using namespace std;
void kiir(const int& szam) { // Nem módosíthatjuk az értékét
cout << "Szam: " << szam << endl;
}
int main() {
int x = 42;
kiir(x); // Biztonságos, mert az érték nem változik
return 0;
}
Miért hasznos a const
?
- Megakadályozza a véletlen módosításokat.
- Segít optimalizálni a teljesítményt, mert elkerüljük a másolást.
A pointerek is átadhatók referenciaként, így módosíthatjuk magát a pointert is.
#include <iostream>
using namespace std;
void allit(int*& ptr) { // Pointert referencia szerint adunk át
*ptr = 20; // A mutatott értéket módosítjuk
}
int main() {
int szam = 10;
int* p = &szam;
allit(p);
cout << "Szam erteke: " << szam << endl; // Kiírja: 20
return 0;
}
✔ Ha az adatok nagyok (pl. vektorok, osztályok, nagy struktúrák), hogy elkerüljük a felesleges másolást.
✔ Ha módosítani akarjuk az eredeti változó értékét a függvényen belül.
✔ Ha egy változót akarunk hatékonyan átadni, de nem akarjuk módosítani (const &
).
✔ Ha dinamikusan kezelt objektumokkal dolgozunk (std::vector
, std::string
).
const
-tal: Megakadályozza a módosítást, de hatékonyabb, mint az érték szerinti átadás.