Pass by pointer & Pass by reference [duplicate]
Możliwy duplikat:
jakie są różnice między zmienną wskaźnika a zmienną odniesienia w C++?
czy są korzyści z przechodzenia przez wskaźnik nad przechodzeniem przez odniesienie w C++?
W obu przypadkach osiągnąłem wynik. Więc kiedy jeden jest preferowany nad drugim? Jakie są powody, dla których używamy jednego nad drugim?
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x=*y;
*y=z;
}
void swap(int& x, int& y)
{
int z = x;
x=y;
y=z;
}
int main()
{
int a = 45;
int b = 35;
cout<<"Before Swap\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(&a,&b);
cout<<"After Swap with pass by pointer\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(a,b);
cout<<"After Swap with pass by reference\n";
cout<<"a="<<a<<" b="<<b<<"\n";
}
Wyjście
Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45
After Swap with pass by reference
a=45 b=35
5 answers
Odniesienie jest semantycznie następujące:
T& <=> *(T * const)
const T& <=> *(T const * const)
T&& <=> [no C equivalent]
(C++11)
Podobnie jak w przypadku innych odpowiedzi, następująca z C++ FAQ jest jednolinijkową odpowiedzią: referencje, gdy jest to możliwe, wskaźniki, gdy są potrzebne.
Przewaga nad wskaźnikami polega na tym, że potrzebujesz wyraźnego rzutu, aby przekazać NULL. Ale to wciąż możliwe. Z testowanych przeze mnie kompilatorów, żaden nie wyświetla ostrzeżenia dla:
int* p() {
return 0;
}
void x(int& y) {
y = 1;
}
int main() {
x(*p());
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-19 05:04:48
W rzeczywistości większość kompilatorów emituje ten sam kod dla obu wywołań funkcji, ponieważ odwołania są zazwyczaj implementowane za pomocą wskaźników.
Zgodnie z tą logiką, gdy argument (non-const) reference type jest używany w ciele funkcji, wygenerowany kod po prostu po cichu operuje na adresie argumentu i dereferuje go. Ponadto, gdy zostanie napotkane wywołanie takiej funkcji, kompilator wygeneruje kod, który przekazuje adres argumentów zamiast kopiowanie ich wartości.
Zasadniczo odniesienia i wskaźniki nie różnią się zbytnio z punktu widzenia implementacji, główna (i bardzo ważna) różnica tkwi w filozofii: odniesienie to sam obiekt, tylko o innej nazwie.
Odniesienia mają jeszcze kilka zalet w porównaniu ze wskaźnikami (np. nie mogą być NULL
, więc są bezpieczniejsze w użyciu). W związku z tym, jeśli można używać C++, to przechodzenie przez odniesienie jest ogólnie uważane za bardziej eleganckie i powinno być preferowane. Jednakże, w C, nie ma przejścia przez odniesienie, Więc jeśli chcesz napisać kod w C (lub, horribile dictu, kod, który kompiluje się zarówno z kompilatora C i C++, choć to nie jest dobry pomysł), będziesz musiał ograniczyć się do używania wskaźników.
Pass by pointer jest jedynym sposobem, w jaki możesz przejść "przez odniesienie" w C, więc nadal widzisz, że jest używany dość często.
Wskaźnik NULL jest przydatną konwencją do mówienia, że parametr jest nieużywany lub nieprawidłowy, więc użyj wskaźnika w tym przypadku.
Odniesienia nie mogą być aktualizowane po ich ustawieniu, więc użyj wskaźnika, jeśli chcesz je ponownie przypisać.
Preferuj odniesienie w każdym przypadku, gdy nie ma dobrego powodu, aby tego nie robić. Zrób to const
jeśli możesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-20 05:18:40
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-23 07:28:00
Używaj referencji przez cały czas, a wskaźniki tylko wtedy, gdy musisz odwołać się do NULL
, których Referencja nie może się odnosić.
Zobacz ten FAQ : http://www.parashift.com/c++ - faq-lite / referencje. html#faq-8.6
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-20 05:26:04