C ++ разница между ссылками, объектами и указателями - PullRequest
15 голосов
/ 11 июля 2010

Это вопрос из экзамена на продвинутом курсе по ООП, который преподается на C ++ (в университете TAU, в этом семестре):

Q: В чем разница между указателем C ++ и ссылкой?

A.  A reference is the entire object while a pointer is only the address of it.
B.  The same meaning, and difference is only in syntax and usage.
C.  The syntax used to access the object.
D.  Pointers are simple address to the object while a reference uses the virtual table.

Какой правильный ответ?

Учитель курса утверждает, что A является правильным, и что ссылка на объект - это фактически сам объект.Это верно?Я понимаю, что доступ к ссылке эквивалентен доступу к самому объекту, однако при уничтожении ссылки мы не разрушаем сам объект.Ссылка - это альтернативное имя для объекта, но говоря, что reference == object true?

Кстати, лектор дал следующую ссылку на faq в поддержку своего утверждения , цитата:

"Важное примечание. Несмотря на то, что ссылка часто реализуется с использованием адреса на базовом языке ассемблера, не следует воспринимать ссылку как забавный указатель на объект. Ссылка - это объект . Это не указатель на объект и не копия объекта. Это объект. "

Но, тем не менее, я считаю,это неверно.

Ответы [ 11 ]

37 голосов
/ 11 июля 2010

Они все не правы.

A ссылка по сути является синонимом для другого объекта. Внутренне это часто реализуется как указатель, но имеет синтаксис, как если бы это был объект, к которому он обращается.

A указатель - это отдельный объект, в котором хранится адрес памяти объекта, на который он указывает (или 0, если он не указывает на объект).

Вы могли бы сказать, что ссылка - это объект, на который она ссылается (это, безусловно, действует так), но это не так. Если ссылка выходит из области видимости, то объект, на который она ссылается, не разрушается, поэтому ссылка не является объектом.

7 голосов
/ 11 июля 2010

Существует различие между ссылкой и объектом - вы можете иметь несколько ссылок на один и тот же объект.Объект имеет «идентичность», в то время как сама ссылка на самом деле не такова.

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

5 голосов
/ 11 июля 2010

(B) является ближайшим, но все еще не совсем правильным. Ссылка является синтаксическим сахаром для константного указателя. Как и указатель const, он должен быть привязан к lvalue при инициализации и никогда не может быть восстановлен. Так же, как указатель const, он полиморфен.

РЕДАКТИРОВАТЬ: Краткое доказательство того, что (A) является неправильным, поскольку по крайней мере пару человек защищают его:

struct A { int x; int f() { return 1; } }
struct B : public A { int y; int f() { return 2; } }

B b;
A& a = b;

assert(sizeof(a) == sizeof(b)); // fail
assert(a.f() == b.f()); // fail again
4 голосов
/ 11 июля 2010

Для того, чтобы на мгновение забраться на мою лошадь для хобби, университеты не занимаются обучением людей программированию на определенных компьютерных языках. Тот факт, что они это делают, является просто показателем того, насколько они деградировали за последние 30 лет. Я работал в Лондонском университете с 1979 по 1983 год в качестве специалиста и программиста по микробиологии, и студенты-микробиологи (обратите внимание, не студенты CS!) Должны были научиться пользоваться компьютерами и программировать более или менее самостоятельно, что они сделали столько, сколько им нужно.

Но в наши дни даже студенты CS, кажется, все обманывают и проверяют на этих «знаниях» практически невозможно провалить тесты, подобные тем, которые цитирует OP.

Г !!!

3 голосов
/ 12 июля 2010

Важно различать:

  • Ссылка как выражение
  • Ссылка сама по себе

Часто задаваемые вопросы и учитель, кажется, говорят опервый пункт, но вопрос учителя формулируется так, как будто он спрашивает о втором пункте.Чтобы объяснить точку зрения FAQ, рассмотрим то, что Стандарт описывает как самый первый этап обработки выражений

Если выражение изначально имеет тип «ссылка на T» (8.3.2, 8.5.3), тип настраивается на «T» перед любым дальнейшим анализом, выражение обозначает объект или функцию, обозначенную ссылкой, и выражение является lvalue

После это преобразование, ссылка и объект или функция, которые она обозначает, больше не может быть распознано с помощью этого выражения.Но это не делает ссылку эквивалентной объекту.Первое просто относится к последнему .Тем более, что ссылки могут также ссылаться на функции.

Теперь сама ссылка - это просто сущность, которая ссылается на объект или функцию, но не хранит что-то самостоятельно.

Та же самая ошибка в споре иногда допускается людьми, когда они говорят, что массивы в C будут просто указателями.На самом деле они имеют в виду, что массивы в выражениях являются (в основном) просто указателями.Но это не делает их обоих равными самим по себе.

1 голос
/ 29 августа 2010

Одно из существенных отличий между указателями и ссылками, о которых я не упомянул, состоит в том, что указатель может иметь значение NULL, а ссылка - нет.Это не означает, что объект, на который ссылаются указатели, не может выйти из области видимости, что приводит к тем же типам проблем, с которыми люди сталкиваются с указателями, просто из-за отсутствия состояния «нет назначенного».

1 голос
/ 17 августа 2010

Отвечая на вопрос, неправ ли учитель: Простая логика Строго говоря, это то, что говорит имя (и стандарт): ссылка на (= "имя") объекта, НЕ сам объект. Как было сказано ранее, когда ссылочная переменная выходит за пределы области видимости, деструктор объекта не вызывается, поэтому ссылка является , а не объектом.

#include <iostream>
class A {
public:
    ~A()
    {
            std::cout << "~A() called.\n";
    }
};
void f(A &a)
{
    // a running out of scope...
}
int main()
{
    A a;
    std::cout << "calling f()\n";
    f(a);
    std::cout << "done calling f()\n";
    return 0;
}
1 голос
/ 11 июля 2010

Все ответы неверны, А ближайший.

Указатель - это адрес объекта, который сам является объектом.
«Объект» - это «что-то» где-то в памяти. Экземпляр класса, int, float и т. Д.
Ссылка - это альтернативный способ доступа к объекту . Это ссылка на объект, но не сам объект. Это может или не может быть реализовано как указатель. Вы можете думать об этом как об альтернативном имени объекта, но это не совсем правильно. Самое близкое правильное описание, которое я могу придумать, это «альтернативный интерфейс для доступа / манипулирования объектом» (к сожалению, «интерфейс» звучит вводящим в заблуждение, если принять во внимание ООП, хотя это (ИМО) наиболее правильный вариант).

0 голосов
/ 24 октября 2011

Давайте оценим один вариант за раз -

A.Ссылка - это весь объект, а указатель - только его адрес.

Нет такой вещи, как "весь объект"!это просто объект.Многие ссылки могут указывать на объект и затем перестать ссылаться на него, даже если сам объект продолжает существовать.Неправильный ответ!

B.То же значение, и различие только в синтаксисе и использовании. Это НЕ одно и то же.Например, когда вы получаете & ref - вы не можете сделать ref ++, где, как если бы вы получили * ptr, вы можете сделать ptr ++.Указатель не только позволяет получить доступ к объектам, но и позволяет использовать арифметику указателей;таким образом, с помощью указателей вы можете передать не только 1 адрес (и изменить этот адрес), но и весь массив произвольного местоположения с одинаковым синтаксисом.Вы не можете сделать это со ссылкой!Неправильный ответ!

C.Синтаксис, используемый для доступа к объекту. Не совсем понял, как он представляет собой разницу между двумя концепциями.Неправильный ответ!

D.Указатели - это простой адрес объекта, в то время как ссылка использует виртуальную таблицу. Я не думаю, что существует нечто, называемое виртуальной таблицей.Указатели обычно указывают в куче, где в качестве ссылки указатель находится внутри стека.Неправильный ответ!

Все не так ...

Дипан.

0 голосов
/ 11 июля 2010

Я считаю, что ваш учитель путает метафору и конкретное утверждение. Ссылка определенно является , а не фактическим объектом, а реализована как «забавно выглядящий указатель», но смысл этого утверждения в том, что вы должны рассматривать ссылку как фактическую объект, на который ссылаются, вы не должны думать или программировать, как будто вы обрабатываете указатель. Синтаксически доступ к ссылке на объект идентичен доступу к самому объекту, за исключением нескольких случаев, упомянутых в комментариях ниже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...