2010-12-13 21 views
23

Czy przekazywanie argumentu wskaźnik, przekazać według wartości w C++? Ponieważ widzę, że wszelkie zmiany wskaźnika jako takie nie są odzwierciedlone poza metody. Zmiany dokonane przez wyłuskiwanie wskaźnika są jednak odzwierciedlane.Czy przekazywanie argumentu wskaźnik, przekazać według wartości w C++?

Czy w takim przypadku akceptuje się/stosuje standardową procedurę używania wskaźnika do wskaźnika jako argumentu funkcji do modyfikowania wartości wskaźnika jako takiej w funkcji?

+5

Wskaźnik jest przekazywany przez wartość, ale obiekt wskazywany przez wskaźnik może być modyfikowany przez funkcję (zależnie od klasy const). – dreamlax

Odpowiedz

24

Tak dla obu.

Wskaźniki są przekazywane według wartości, jak cokolwiek innego. Oznacza to, że zawartość zmiennej wskaźnika (adres wskazanego obiektu) jest kopiowana. Oznacza to, że jeśli zmienisz wartość wskaźnika w ciele funkcji, ta zmiana nie zostanie odzwierciedlona w zewnętrznym wskaźniku, który będzie wskazywał na stary obiekt. Ale możesz zmienić wartość wskazywanego obiektu.

Jeśli chcesz odzwierciedlić zmiany wprowadzone w wskaźniku do zewnętrznego wskaźnika (wskaż coś innego), potrzebujesz dwóch poziomów pośrednich (wskaźnik do wskaźnika). Podczas wywoływania funkcji jest to wykonywane przez umieszczenie przed nazwą wskaźnika wskaźnika &. Jest to standardowy sposób robienia rzeczy.

Podczas korzystania z C++, korzystamy z referencji do wskaźnika (od tego momentu również do wskaźnika do wskaźnika).

Dla dlaczego odniesienia powinny być korzystne wskaźniki, istnieje kilka powodów:

  • referencje wprowadzić mniej syntaxic hałasu niż wskaźniki w ciele funkcji
  • referencje zachować więcej informacji niż wskaźniki, niż może być przydatne dla kompilatora

Wady odniesień są głównie:

  • łamią prostą regułę C-pass-by-value, co powoduje, że zrozumienie zachowania funkcji dotyczącej parametrów (czy zostaną zmienione?) Jest mniej oczywiste. Potrzebujesz również prototypu funkcji. Ale to nie jest tak naprawdę gorsze od poziomów wielu wskaźników wymaganych przy korzystaniu z C., które nie są obsługiwane przez C, co może być problemem podczas pisania kodu, który powinien działać zarówno z programami C i C++ (ale to nie jest najlepszy zwykły przypadek).

W szczególnym przypadku wskaźnika do wskaźnika różnica jest w większości prostsza, ale za pomocą odwołania może być również łatwo usunąć oba poziomy wskaźników i przekazać tylko jedno odwołanie zamiast wskaźnika do wskaźnika.

+1

Dlaczego preferowane jest stosowanie wskaźników do referencji? – Arafangion

+0

@Arafangion: Edytowałem swoją odpowiedź, aby wyjaśnić, dlaczego preferencje powinny być preferowane względem wskaźników. – kriss

+0

Przypuszczam, że to subiektywne - wolę używać referencji, ponieważ przenoszę odpowiedzialność za sprawdzanie wskaźnika pustego na dzwoniącego i zwykle nie dbam o kompatybilność z C. Jednak nie jestem pewien, czy jestem sprzedany na "Potrzebujesz również prototypów funkcji, aby mieć pewność, że wartość nie zostanie zmieniona" - tak jest w przypadku wielu klas w C++ - mogą one same być wskaźnikami i mogą lub nie mogą współdzielić danych. Powiedziałbym, że wolę przekazywać wartość i pozwalać klasie dbać o wszelkie wskaźniki, jeśli są potrzebne, chyba że zwrócę referencje rvalue, które powinny być natychmiast ustawione, niezależnie, +1 – Arafangion

0

Albo wskaźnik do wskaźnika, albo odniesienie do wskaźnika, jest tym, czego użyłbyś, gdybyś chciał zmienić sam wskaźnik. Na twoje oryginalne pytanie, technicznie, tak, wszystkie parametry są przekazywane przez wartość.

+7

"Wszystkie parametry są przekazywane przez wartość" Nie, argumenty przekazane przez odniesienie nie są przekazywane przez wartość. –

0

Tak jest, ponieważ w C

W tym przypadku, jest to do przyjęcia/standardowa procedura użyciu wskaźnika do wskaźnika jako argumentu w funkcji modyfikacji wartości wskaźnika jako takiego w funkcji ?

W takim przypadku? Co chcesz?Możesz użyć prawdziwych referencji z modyfikatorem &.

void func(type &ref); 
6

Rozumiem tutaj zamieszanie. Pojęcia "przekazywać według wartości" i "przekazywać przez odniesienie" nie są tak jasne, nawet jeśli wydają się takie. Należy pamiętać, że komputer nie zna tych pojęć i nie zachowuje się zgodnie z nim. Komputer nie wie o typach. W związku z tym nie czyni rozróżnienia wskaźników i wartości. Pozwól mi spróbować wyjaśnić i przez przykład:

void func1(int x) 
{ 
    x = 5; 
} 

void func2(int *x) 
{ 
    int a; 
    x = &a; 
} 

Operacja jest taka sama dla obu funkcji w maszynie: To staje się argument i zmienia go. Zauważ, że w drugiej funkcji nie modyfikuje * x, modyfikuje x.

Teraz możemy wywołać te funkcje,

int y = 10; 

func1(y); //value of y does not change 

func2(&y); //value of &y does not change, but the value of the address which y points may change. 

Wolę powiedzieć, że zasadzie każde wywołanie funkcji jest „wywołanie przez wartość”. Ale w przypadku typu wskaźnika mamy sposób na zmianę zawartości innego adresu w pamięci.

Gdybyśmy napisany func2 jak

void func2(int *x) 
{ 
    *x = 5; 
} 

Wtedy byłby to prawdziwy przypadek „rozmowy przez odniesienie”.

Powiązane problemy