2013-06-13 10 views
9

czytałem C++ Primer i zauważyłem, że nie jest to stwierdzenie mówi:Czy można zdefiniować wskaźnik do odniesienia?

Because references are not objects, they don't have addresses. Hence, we may not define a pointer to a reference.

Ale ja po prostu napisał przykładowy kod i pokazuje, że jest to możliwe, aby utworzyć wskaźnik do odniesienia (zmienna d).

Kod jest zamieszczona poniżej:

#include <iostream> 
using namespace std; 

int main(){ 
    int a = 1024; 

    int &b = a; // a reference to int 
    int &c = b; // a reference to another reference 
    int *d = &b; // a pointer to a reference 
    int *(&e) = d; // a reference to a pointer 

    a = 100; 
    cout << b << endl; 
    cout << c << endl; 
    cout << *d << endl; 
    cout << *e << endl; 
} 

Więc coś nie tak z moim teście? Lub oświadczenie w C++ Primer jest złe?

Czytam C++ Primer piąte wydanie. Oświadczenie znajduje się na stronie 52, 2.3.2.

+0

@taocp oops, edytowane :-) – yegle

+2

Przełącz 'e' na' int & (* e) = d; 'i otrzymasz' error: nie można zadeklarować wskaźnika 'int &' 'z GCC. To sprawia, że ​​całkiem jasne jest, że 'd' nie jest wskaźnikiem odniesienia. – chris

+0

Pomyśl o referencji jako alias do oryginalnego obiektu. Referencje nie przydzielają, dealloc pamięci. Jak już wspomniano, możesz wskazać obiekt, do którego odnosi się nazwa aliasu, ale nic w pamięci nie reprezentuje samego aliasu (jest to tylko kod). Natomiast wskaźnik alokuje pamięć i przechowuje wartość (nawet jeśli ma wartość NULL). –

Odpowiedz

9

Cytat ma rację, ponieważ robisz wskaźnik wskazujący na oryginalny obiekt, a nie jego referencję. Poniższy kod pokazuje ten fakt:

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    int a = 0; 
    // two references referring to same object 
    int& ref1_a = a; 
    int& ref2_a = a; 
    // creating a different pointer for each reference 
    int* ptr_to_ref1 = &ref1_a; 
    int* ptr_to_ref2 = &ref2_a; 

    printf("org: %p 1: %p 2: %p\n", &a, ptr_to_ref1, ptr_to_ref2); 

    return 0; 
} 

wyjściowa:

org: 0x7fff083c917c 1: 0x7fff083c917c 2: 0x7fff083c917c 

Jeśli powiedziałeś, że jesteś w stanie zrobić wskaźnik dla odniesienia, to powyższe wyjście powinno być inaczej.

+1

Zmień 'printf' na' printf ("0:% X 1:% X 2:% X \ n", & a, ptr_to_ref1, ptr_to_ref2); 'sprawiłoby, że byłoby to bardziej oczywiste :-) – yegle

+2

Łączenie zwykłego przeszukiwania stackoverflow, printf powinien mieć% p placeholders, nie% x (wskaźniki 64-bitowe vs. 32-bitowe ints, yada yada). +1 mimo wszystko za dobre wyjaśnienie. – Yamodax

+0

@yegle: Niezły punkt. Zawarłem to w moim przykładowym kodzie. Dziękuję Ci! – keelar

7

Co mówi książka jest poprawna. Twój wskaźnik wskazuje na a, a nie na samą referencję (b), ponieważ samo odniesienie (b) nie istnieje w pamięci jako takie i dlatego nie ma adresu.

+3

Odwołanie * może * posiadać pamięć, na przykład jeśli jest przekazywane do funkcji - kompilator może ją wewnętrznie zaimplementować jako wskaźnik. Ta implementacja nie jest jednak dla ciebie widoczna. –

+0

Masz oczywiście rację. – Yamodax

5

Nie, nie można wskazać odniesienia. Jeśli użyjesz adresu-operatora &, otrzymasz adres obiektu, do którego się odwołujesz, a nie sam odnośnik.

0

Pomyśl o referencji jako alias do oryginalnego obiektu. Referencje nie przydzielają, dealloc pamięci. Jak już wspomniano, możesz wskazać obiekt, do którego odnosi się nazwa aliasu, ale nic w pamięci nie reprezentuje samego aliasu (jest to tylko kod). Natomiast wskaźnik alokuje pamięć i przechowuje wartość (nawet jeśli ma wartość NULL).

Powiązane problemy