Возможно ли, что набор содержит два общих указателя на один и тот же объект? - PullRequest
3 голосов
/ 05 октября 2011

В моем коде у меня есть два вектора:

vector<lipid*> lipids;
vector<shared_ptr<bead> > ions;

Класс lipid:

class lipid{
 public:
  lipid();
  lipid(double x, double y, bool up, int LID);
  ~lipid();
  void makeMe(int LID);
  std::tr1::shared_ptr<bead> head;
  std::tr1::shared_ptr<bead> body;
  std::tr1::shared_ptr<bead> tail;
  int LID;
  vec direction;
};

И я создаю бусинки головы, тела, хвоста в конструкторе липидов.

std::tr1::shared_ptr<bead> he(new bead);
std::tr1::shared_ptr<bead> bo(new bead);
std::tr1::shared_ptr<bead> ta(new bead);
this->head = he;
this->body = bo;
this->tail = ta;

Некоторые из липидных головок вставляются в вектор ионов следующим образом:

vector<lipid*>::iterator lit = lipids.begin();
while (lit != lipids.end()){
  lipid * l = *lit++;
  if (l->head->charge != 0) this->ions.push_back(l->head);
}

, где charge - целочисленное свойство bead. У меня также есть map<vector<int>, set<shared_ptr<bead> > > для хранения некоторых бусин с названиями коробок. Чтобы добавить bead в любое из значений карты, которые я использую:

bead b = l->head; //b white also be accessed through a beads vector that holds a shared pointer to all beads in the simulation
vector<int> t = b->getBox(); //a function that returns a valid box
boxes[t].insert(b);

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

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

Надеюсь, все это имеет для вас смысл.

Ответы [ 4 ]

3 голосов
/ 05 октября 2011

Консультации http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/shared_ptr.htm#comparison (или TR1, или стандарт C ++ 11).

Если два shared_ptr указывают на один и тот же объект, то они сравниваются как эквивалентные по operator<,так что они дубликаты в отношении std::set<shared_ptr<bead> >.

3 голосов
/ 05 октября 2011

Нет, это невозможно.

std::set гарантирует отсутствие дубликатов.Является ли экземпляр дубликатом другого, решается путем применения второго аргумента шаблона, который по умолчанию равен std::less.

. Стандартная библиотека предоставляет operator <, который работает на std::shared_ptr, выполняя сравнение меньше, чем сравнениена основные указатели.

3 голосов
/ 05 октября 2011

Какую функцию сравнения вы используете? Если это значение по умолчанию (std::less), то вы не можете иметь два указателя на один и тот же объект в std::set; в этом отношении я не могу думать о возможной функции сравнения, которая отвечает требованиям, и позволила бы это.

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

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

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

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

Если использование std :: set ограничивало уникальные записи, то оно должно работать как положено, однако если вы ожидаете дублирования, вам понадобится другой контейнер, такой как std :: vector.

Надеюсь, эта помощь

...