2013-06-13 5 views
9

Я читал C++ Primer, и я заметил, что есть заявление говорит:Можно ли указать указатель на ссылку?

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

Но я просто написал пример кода, и показывает, что можно создать указатель на ссылку (переменная d).

код размещен ниже:

#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; 
} 

Итак, все, что случилось с моим испытанием? Или заявление в C++ Primer неверно?

Я читаю C++ Primer пятое издание. Заявление приведено на стр. 52, 2.3.2.

+0

@taocp oops, под редакцией :-) – yegle

+2

Переключить 'e' в' int & (* e) = d; 'и вы получите' error: не можете объявить указатель на 'int &' 'из GCC. Это делает довольно очевидным, что 'd' не является указателем на ссылку. – chris

+0

Подумайте о ссылке как псевдоним исходного объекта. Ссылки не выделяют, dealloc память. Как было указано, вы можете указать на объект, на который ссылается псевдоним, но в памяти нет ничего, чтобы представлять сам псевдоним (это только код). В отличие от этого указатель выделяет память и сохраняет значение (даже если значение равно NULL). –

ответ

9

Цитата правильная, так как вы делаете указатель, указывающий на исходный объект, а не на его ссылку. Приведенный ниже код показывает этот факт:

#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; 
} 

выход:

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

Если вы сказали, что вы в состоянии сделать указатель на ссылку, то выше выход должен быть разным.

+1

Измените 'printf' на' printf («0:% X 1:% X 2:% X \ n», & a, ptr_to_ref1, ptr_to_ref2); 'сделает его более очевидным :-) – yegle

+2

Присоединение к обычной stackoverflow nitpicking, printf должен иметь% p placeholders, а не% x (64-разрядные указатели против 32-битных ints, yada yada). +1 в любом случае для хорошего объяснения. – Yamodax

+0

@yegle: Хорошая точка. Я включил это в свой примерный код. Спасибо! – keelar

7

Что говорит книга правильно. Ваш указатель указывает на a, а не на саму ссылку (b), поскольку сама ссылка (b) не существует в памяти как таковая и поэтому не имеет адреса.

+3

Ссылка * может * иметь память, например, если она передана в функцию - компилятор может реализовать ее как указатель внутри. Однако эта реализация не раскрывается вам. –

+0

Вы, конечно, правы. – Yamodax

5

Нет, вы не можете сделать указатель на ссылку. Если вы используете адрес-оператора &, он получает адрес объекта, на который вы ссылаетесь, а не сама ссылка.

0

Подумайте о ссылке в качестве псевдонима к исходному объекту. Ссылки не выделяют, dealloc память. Как было указано, вы можете указать на объект, на который ссылается псевдоним, но в памяти нет ничего, чтобы представлять сам псевдоним (это только код). В отличие от этого указатель выделяет память и сохраняет значение (даже если значение равно NULL).