c ++ ссылка на вектор выдает? - PullRequest
3 голосов
/ 20 июня 2011

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

(*myVector)[i]->myFunction();

и все работало отлично. myFunction () будет переводить любой объект, который был текущим индексом myVector.

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

myVector[i].myFunction();

Он компилируется, я обнаружил, что myFunction () больше не дает такие же результаты, как раньше. Я использовал точку останова и увидел, что она изменяет атрибуты, как и должно быть, однако эти изменения никогда не вносились в исходный объект. Окончательного перевода не было, хотя точка останова показала, что происхождение myVector [i] изменилось.

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

(*myVector)[i].myFunction();

и то же самое, оно скомпилировано, но не работает.

Наконец, я попытался просто передать ссылку на первый объект в векторе, и, конечно, это сработало просто:

myObject.myFunction();

Есть ли какая-то внутренняя вещь, которую я упускаю в ссылках на векторы? Почему указатель на вектор указателей работает, а ссылка на вектор объектов - нет? Разве переданный вектор не должен быть псевдонимом исходного вектора? Почему ссылка показывает изменения, а не объект, на который она ссылается?

Почему мои изменения не меняются, если я не использовал вектор указателей вместо вектора объектов.

Ответы [ 4 ]

9 голосов
/ 20 июня 2011

Подожди минуту. Когда вы изменили этот фрагмент:

(*myVector)[i]->myFunction()

К этому:

myVector[i].myFunction()

Вы фактически изменили две вещи:

  1. myVector перешел от указателя к ссылке;
  2. Тип элементов внутри myVector перешел от указателя к простому типу значения.

Если вы изменили тип элементов на простой тип значения (как в std::vector<int*> на std::vector<int>), то при добавлении их в ваш вектор они копируются в него. (То, как вектор передается, то есть указатель или ссылка, не влияет на это поведение. Способ передачи вектора и способ передачи объектов внутри вектора полностью независим.) Это означает, что всякий раз, когда вы вносите в них изменения, вы меняете только версию, которая находится внутри вектора.

Нет ничего плохого в использовании вектора, который содержит указатели (при условии, что вы управляете памятью разумным образом). Если вы хотите, чтобы изменения в версии вашего вектора были реплицированы на оригиналы, вам придется использовать ссылки или указатели. Так как в мире больно иметь вектор, содержащий ссылки (как в std::vector<int&>), если это вообще возможно, вы, вероятно, предпочтете указатели.

1 голос
/ 20 июня 2011

Проблема не имеет ничего общего с тем, держите ли вы указатель или ссылку на вектор.Это связано с тем, что содержит вектор.Если вектор содержит указатели, то при изменении указательных объектов в векторе будут затронуты любые другие указатели или ссылки, существующие для тех же объектов.Но если ваш вектор содержит объекты (по значению), вы копируете их при вставке, и изменения внутри вектора не будут видны снаружи, и наоборот.

Это фундаментальная природа указателей и ссылок- если это не имеет смысла, вам следует искать достойную книгу по C ++.

1 голос
/ 20 июня 2011

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

  1. Вы поместили копии объектов в вектор и ожидаете, что оригиналы будут изменены?

  2. Проблема может заключаться в том, что конструктор копирования ваших объектов не копирует все элементы.Вектор растет?Если объекты перемещаются внутри вектора, важно, чтобы конструктор копирования работал.

Наконец:

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

Здесь не должно иметь значения, передаете ли вы указатель на вектор или ссылку на вектор.Концептуально они разные (ссылки не могут быть нулевыми, например), но в реализации они оба являются указателями на вектор, и вектор не передается по значению.

0 голосов
/ 20 июня 2011

Когда вектор хранит объекты, он сохраняет копию исходного объекта, который был передан. Поэтому, когда вы делаете что-то подобное,

yourClass yourObj;
std::vector<yourClass> yourVector;
yourvector.push_back(yourObj);
yourvector[0].myFunction();

только объект на yourvector[0] изменяется, потому что это копия оригинала.

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