Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

referencja i dereferencja ( teoria )

Ostatnio zmodyfikowano 2015-10-17 14:13
Autor Wiadomość
Dizip
Temat założony przez niniejszego użytkownika
referencja i dereferencja ( teoria )
» 2015-10-14 16:04:03
Mógłby mi ktoś wyjaśnić czym jest referencja i dereferencja. Używam tego w kodzie, ale nie umiem komuś wyjaśnić czemu się tego używa i jak to dokładnie działa.
Jest tu jakiś dobry teoretyk, który to wyjaśni na jakims przykladzie?
P-138563
Monika90
» 2015-10-14 16:35:16
Referencja to zmienna (lub wartość zwrócona z funkcji), która jest typu referencyjnego, to znaczy: typ tej zmiennej ma postać T& lub T&&. Służy to do pośredniego dostępu do obiektów, np.
C/C++
int & f( int & x )
{
    const int & y = x;
    return x;
}
x i y to referencje do typu int, funkcja f też zwraca referencję.

Referencję można traktować jako nową nazwę dla już istniejącego obiektu.

Typowe zastosowanie to przekazywanie argumentów do funkcji, gdy chcesz by funkcja miała dostęp do oryginalnego obiektu, a nie jego kopii. Podobnie przy zwracaniu referencji - chcesz by kod wywołujący funkcję miał dostęp do oryginału. I wreszcie referencja jako składowa klasy, daje obiektom tej klasy dostęp do jakichś innych obiektów, które fizycznie znajdują się poza obiektami tej klasy.


Dereferencja to operacja * zastosowana do wskaźnika lub iteratora:
C/C++
int x = * ptr; //dereferencja wskaźnika ptr
Daje to dostęp do obiektu na który wskaźnik wskazuje. Operator * jest tutaj czasami nazywany operatorem dereferencji.
P-138564
ktos-tam
» 2015-10-14 17:05:00
Referencja:
Załóżmy, że mamy jakiś duży obiekt np. string z 1000 znaków. Posiadamy także funkcję, która dodaje nam jakiś znak na koniec string'a. Jeżeli operacja odbywała by się standardowo, czyli np tak:

//string a
a = dodaj('x', a);

To zauważ, że potrzeba wtedy wykonać bardzo kosztowne operacje - skopiować "a" (przekazywanie jako parametr), a następnie skopiować jeszcze raz (przypisanie). Ten problem rozwiązuje referencja. Dzięki niej nie kopiujesz ciągu "a", tylko się do niego odwołujesz. Różnica w kodzie jest niewielka:

//"tradycyjnie"
string dodaj(char c, string s);

//referencja
string dodaj(char c, string& s);

Musisz jednak pamiętać, że operujesz wtedy na właściwej zmiennej, więc możesz wtedy niechcący naruszyć jej zawartość. Jeżeli chcesz tylko odczytać tę wartość, lepiej użyj stałej referencji (zgodnie z zasadą hermetyzacji):

//deklaracja
void zrobCokolwiek(const string& s);

Ogólnie nie jeżeli chcemy modyfikować zmienną, powinniśmy wykorzystać wskaźnik, dla zaznaczenia fakty modyfikacji. Tak się przyjęło. Dla mnie nie ma to sensu.


Dereferencja:
Jeżeli masz wskaźnik na jakąś zmienną np.:

int a;
int* wsk_a = &a;

i chcesz odczytać wartość zmiennej spod wskaźnika, to musisz dokonać jego dereferencji np.:

cout<<*wsk_a;

Operatorem dereferencji jest "*". Jeżeli jej nie dokonasz, to w efekcie wyświetli ci się wartość wskaźnika, czyli adres zmiennej "a".

cout<<wsk_a;
//i ukazuje ci się "0x" i kilka cyfr w systemie szesnastkowym

Tak więc dereferencja jest odwołaniem się do wartości zmiennej, na którą wskazuje wskaźnik.
P-138566
C-Objective
» 2015-10-15 16:36:54
Wyobraź sobie, że każda zmienna to tak naprawdę dwie zmienne. Jedna typu x a druga typu int.
Mamy zmienną
int a = 3;
.
Jak narazie nie przyda nam się co to ta druga zmienna. Uruchom taki program (Użyj starego kompilatora albo powstawiaj
int
 w odpowiednich miejscach):
C/C++
#include <stdio.h>
main() {
    i = 5;
    printf( "Zmienna a to %d\n", i );
    printf( "A jej drugi element to %p", & i );
    return 0;
}
Więc widzisz drugą zmienną. Czym ona jest? Adresem tej pierwszej wydrukowanej zmiennej. Jak zrobisz coś takiego:
C/C++
#include <stdio.h>
main() {
    i = 10;
    printf( "%d\n", i );
    scanf( "%d\n", i );
    printf( "%d", i );
    return 0;
}
Jak widzisz, po wpisaniu zmienna się nie zmienia. Dlatego że funkcja scanf potrzebuje WSKAŹNIKA.
Wskaźnik uzyskuje się dodając &. Aby z wskaźnika zrobić zmienną, dodaj do niej *. Funkcja scanf.
Otrzymała rozkaz by pobrać liczbę, ale gdzie ją pobrać? No więc scanf nie wie, więc podajesz jej adres zmiennej, a ona go nadpisuje.
Normalnie, kopiujesz zmienną podając ją funkcji. Gdy użyjesz wskaźnika - Nie musisz nic kopiować - oszczędność pamięci. A z wskaźnikami można
robić więcej ciekawych rzeczy! Pozatym na wikipedii jest dobry artykuł.
P-138605
Dizip
Temat założony przez niniejszego użytkownika
» 2015-10-17 14:13:02
Teraz już wszystko jasne, dziękuje za wytłumaczenie ;)
P-138719
« 1 »
  Strona 1 z 1