Выбор между ссылкой (T &) и константным указателем (T * const) - PullRequest
7 голосов
/ 29 сентября 2011

Есть ли разумный вариант использования, в котором следует использовать const указатель над ссылкой?

T obj;
T &r = obj;  // style-1
T* const p = &obj; // style-2

Оба стиля могут использоваться для одной и той же цели.Я всегда предпочитаю первый стиль в коде и считаю более поздний стиль устаревшим .Однако мне все еще интересно, пропустил ли какой-либо вариант использования, где второй стиль лучше?

Редактировать : Не ограничиваясь приведенным выше примером, я говорю в более широком смысле,

void foo (T& r); // style-1
void foo (T* const p); // style-2

[Я вижу из нескольких ответов, что style-2 позволяет передать значение null.]

Ответы [ 4 ]

5 голосов
/ 29 сентября 2011
Указатель

A const (T* const) может быть NULL, что может быть полезно при передаче аргументов функции или при возврате значений из функции. Например, если у вас есть функция поиска, вы можете захотеть, чтобы она возвращала NULL, если ничего не нашла. Вы не можете сделать это, если он возвращает ссылочный тип.

2 голосов
/ 29 сентября 2011

Позвольте мне выйти на конечность здесь.Поскольку вы явно говорите «константный указатель», я предполагаю, что вы не говорите об аргументах функции или даже возвращаемых значениях функции.Для аргумента функции, передаваемого копией, константность является несущественной деталью реализации:

void foo(T *);          // declaration

void foo(T * const pt)  // implementation,
{ /* ... */ }           // pt is const inside the body (who cares?)

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

for (auto it = box.begin(); it != box.end(); ++it)
{
  T & trinket = *it;     // nice
  T * const ptr = &*it;  // wtpf?

  // ...
}

Поскольку вы редактировали свой вопрос: очевидно, есть разница для аргументов функции.

void foo(T &);
void bar(T *);

В foo вы гарантированно получите работоспособность,ссылка на изменяемый объект;в bar вы должны проверить, является ли указатель не нулевым (давая вам понятие необязательный аргумент).В этом смысле T& и T* на самом деле не сопоставимы.

1 голос
/ 29 сентября 2011

Для аргументов функции я очень предпочитаю указатели на ссылки, потому что я могу сказать на сайте вызова, что параметр является выходным параметром.Если аргумент функции является константной ссылкой, то я предпочитаю ссылки.

Другая большая разница в том, что r не может быть нулевым, поэтому если вам нужно, то вам нужен style-2

0 голосов
/ 29 сентября 2011

1) При использовании ссылки объект должен храниться в переменной.Например, вы не можете сделать это:

void funct (T &);
funct (T ("Calling constructor"));

Должен делать:

void funct (T &);
T obj ("Calling constructor");
funct (obj);

2) При использовании ссылки вы не можете проверить ее значение (например, проверить, что это NULL, чтообычно используется)

Ко всему прочему это одно и то же.

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

...