Как распределять мьютекс между разными экземплярами класса?

Мне было интересно, как разделить мьютекс одного класса между разными экземплярами другого класса.

Прямо сейчас у меня есть класс Indexer, который имеет мьютекс Boost и condition_variable в качестве частных переменных-членов. Я создаю auto_ptr класса Indexer в своей основной и передаю указатель Indexer экземплярам другого класса, Robot.

Мне нравится следующее:

std::auto_ptr<Indexer> index_service(new Indexer());
Robot a(*index_service.get());
Robot b(*index_service.get());
Robot c(*index_service.get());

Конструктор робота:

Robot(Indexer &index_service)
{
  this->index_service = index_service;
}

Заголовок робота выглядит так:

class Robot
{
   public:
     Robot(Indexer &index_service);
   private:
     Indexer index_service;
};

Однако, поскольку мьютексы нельзя копировать, я получаю сообщение об ошибке.

Я думал о создании mutex и condition_variable shared_ptrs, но читал, что это может привести к неожиданному поведению.

Может ли кто-нибудь показать мне правильный / правильный способ сделать это?

Спасибо!


person noko    schedule 03.09.2012    source источник
comment
Я думаю, что в вашем классе Robot вы хотите иметь переменную типа Indexer?   -  person Jon L    schedule 03.09.2012


Ответы (3)


Я не гуру C ++, но, похоже, нечестивое сочетание передачи по ссылке и указателей здесь является проблемой.

В частности, вы делаете это: this->index_service = index_service;
Но значение передается как Indexer &index_service
И поскольку локальный index_service имеет тип Indexer index_service;
я считаю, что присвоение подразумевает копирование.

Я предполагаю, что вам нужен только один экземпляр Indexer, поэтому вы действительно хотите сохранить ссылку на него в своем классе Robot. Для этого вам нужно, чтобы ваш конструктор использовал указатель (что и так дает вам вызов *index_service.get()). Кроме того, вы хотите, чтобы переменная вашего класса была указателем.

person Jon L    schedule 03.09.2012
comment
Кажется, это сработало, спасибо! Мне нужно вернуться к некоторой части моего кода и убедиться, что я не делаю локальные копии ... После этого мне нужно было изменить его на index_service.get () - person noko; 03.09.2012
comment
Ах да, это имело бы смысл. Мое утверждение, которое вызывает вызов * index_service.get (), в любом случае неверно ... Это отменило бы возврат get (давая вам объект), что нормально, если ваш конструктор передается по ссылке, потому что С ++ делает волшебство для тебя ... - person Jon L; 03.09.2012

Объявите статический boost :: mutex в своем классе. Не забудьте определить его в вашем .cpp файле.

Проверьте здесь: Использование статического мьютекса в классе

person Michal M    schedule 03.09.2012

В качестве другого варианта вы можете использовать std::shared_ptr вместо std::auto_ptr и в своем Robot классе изменить Indexer tostd :: shared_ptr`.

class Robot
{
public:
    Robot( std::shared_ptr<Indexer> const &index_service)
    {
        this->index_service = index_service;
}
private:
   std::shared_ptr<Indexer> index_service;
};

std::shared_ptr<Indexer> index_service(new Indexer());
Robot a(*index_service.get());
Robot b(*index_service.get());
Robot c(*index_service.get());
person BigBoss    schedule 03.09.2012