Const Ссылки на указатели - PullRequest
       20

Const Ссылки на указатели

7 голосов
/ 26 марта 2011

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

QList<Item*> itemList;
void addItem(Item* const& item)
{
    itemList.append(item);
}

Теперь я не вижу какой-либо значимой разницы между этим и этим:

QList<Item*> itemList;
void addItem(Item* item)
{
   itemList.append(item);
}

Но, очевидно, кто-то старался изо всех сил использовать такой странный тип. Или, возможно, инструмент рефакторинга пошел не так, как надо.

Есть ли веская причина сохранить подпись этой функции? Какой-то угловой корпус, который ведет себя по-другому? Я не могу думать ни о чем.

Ответы [ 5 ]

6 голосов
/ 26 марта 2011

Единственное отличие состоит в том, что в первой версии вам не разрешено изменять значение локального item внутри функции (вы все равно можете изменить Item, на который она указывает).Поэтому, если вы хотите, чтобы Item* по какой-то причине содержал другое значение, вы были бы вынуждены использовать другой локальный тип Item*, и функция потребляла бы дополнительные sizeof(intptr_t) байты стекового пространства (boo hoo).

Я не знаю, чёрт побери.

1 голос
/ 11 июля 2013

Первое объявление означает «элемент является ссылочной переменной константного указателя».Вы не можете изменить элемент, чтобы он указывал на другие данные типа ITEM, а также он является ссылкой, поэтому он указывает на указатель, который передается в качестве аргумента в вызываемой функции.

Псевдокод: Item * myItem = newРучка();AddItem (myItem);Первое объявление гарантирует, что функция additem не изменит объект пера, поскольку он является постоянной ссылкой, и он не будет копировать содержимое myItem, он просто указывает на место в памяти myItem.Принимая во внимание, что у второго объявления есть издержки на копирование содержимого myItem.

1 голос
/ 26 марта 2011

Это ссылка на константный указатель, что означает, что вы получаете псевдоним для этого указателя, но вы не можете изменить адрес, на который он указывает.

Копия указателя эквивалентна да, если вы сделаете ее константойтоже.

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

0 голосов
/ 30 января 2014

Еще одно существенное отличие, которое мне приходит в голову, заключается в том, что фактические данные передаются в стек.В версии Item* в качестве аргумента передается Item*, для получения которого требуется одна разыменование при значении Item.Тем не менее, поскольку ссылки реализованы в конечном машинном коде с помощью указателей, версия Item* const& фактически передает Item** в качестве аргумента, и для получения значения Item требуется две разыменования.

Это также объясняет, почему вам понадобится дополнительное место в стеке, чтобы получить изменяемую Item* версию - ваш собеседник на самом деле не дал вам Item* в стеке (или в регистре), с которым вы можете возитьсяс, у вас есть только Item** (или Item* const& на земле C ++).

0 голосов
/ 26 марта 2011

Это изменяемая ссылка на постоянный указатель на изменяемое значение.

Ссылка позволила бы вам изменить любую ссылку, но так получилось, что указанный тип является постоянным указателем, поэтому значение указателя изменить нельзя. Значение, на которое указывает указатель, можно изменить.

void* const &

  • Оригинальный указатель: неизменный
  • Ссылочный указатель: неизменный
  • Исходное значение: изменчивый

Передача указателя константы напрямую будет эквивалентна.

void* const

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