2016-03-04 3 views
1

У меня возникла проблема с тем, что мне нужен named_mutex для члена managed_shared_memory внутри класса и получить сообщение «невозможно получить доступ к закрытому члену, объявленному в классе boost :: interprocess :: named_mutex». Тем не менее, я оба получил свой класс из boost :: noncpoyable и использовал std :: unique_ptr с move-semantic в конструкторе без успеха. Использование наддува 1_60 и VS 2010, код следующим образом:boost named_mutex ошибка доступа к частному члену

class FileLocker : private boost::noncopyable 
{ 
public: 
    FileLocker(); 
    ~FileLocker(); 

private: 
    boost::interprocess::managed_shared_memory m_oShMem; 
    std::unique_ptr<boost::interprocess::named_mutex> m_oSetFileMutex; 
}; 

CPP-файл:

FileLocker::FileLocker() 
{ 
    m_oShMem = managed_shared_memory(open_or_create, m_oMemName.c_str(), 1024); 
    m_oSetFileMutex = make_unique<named_mutex>(m_oShMem.find_or_construct<named_mutex>("viVideoFileInOutMutex")()); 
} 

и, наконец, сделать уникальный:

template<typename T> 
std::unique_ptr<T> make_unique() 
{ 
    return std::unique_ptr<T>(new T()); 
} 

template<typename T, typename Ts> 
std::unique_ptr<T> make_unique(Ts&& params) 
{ 
    return std::unique_ptr<T>(new T(std::forward<Ts>(params))); 
} 

Я прочитал несколько StackOverflow-темы, касающиеся этой проблемы , но все они указывают на несовместимость, с которыми я работал ...

Спасибо за помощь!

ответ

2

Оставляя в стороне другие вопросы, вы вызываете named_mutex конструкторы неправильно в двух местах.

Один из них находится здесь:

параметр
m_oShMem.find_or_construct<named_mutex>("viVideoFileInOutMutex")() 

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

m_oShMem.find_or_construct<named_mutex>("viVideoFileInOutMutex")(open_or_create, "named_mutex_name") 

во втором наборе круглых скобок.

Вторая проблема начинается на той же строке:

m_oSetFileMutex = make_unique<named_mutex>(m_oShMem.find_or_construct<named_mutex>("viVideoFileInOutMutex")(open_or_create, "named_mutex_name")); 

Это в основном эквивалентно следующему:

named_mutex *temp = m_oShMem.find_or_construct<named_mutex>("viVideoFileInOutMutex")(open_or_create, "named_mutex_name")); 
m_oSetFileMutex = make_unique<named_mutex>(temp); 

У вас уже есть сырой указатель на named_mutex, что вы передаете в make_unique. Это приводит к make_unique, вызывающему конструктор named_mutex с параметром named_mutex*. Такой конструктор не существует.

+0

Ах. Я даже не видел находки или конструкции. Вероятно, это поможет OP определить недостающий бит. +1 – sehe

+0

Большое спасибо за эту информацию, я попробую это, как только вернусь к проблеме (понедельник)! – gilgamash

+0

Несмотря на то, что вы поместили имя мьютекса в разделяемое место, ваш ответ был абсолютно правильным и помог решить проблему. Благодаря! – gilgamash

0

Во-первых, boost::noncopyable не подлежит движению. Поэтому, если вы не напишете свой собственный конструктор/назначение (Rule Of Five), вы никогда не получите подвижный тип. Компилятор не может создавать специальные элементы перемещения по умолчанию, если база не перемещается.

Вот простодушно фиксированный класс:

Live On Coliru

#include <memory> 
#include <boost/interprocess/sync/named_mutex.hpp> 
#include <boost/interprocess/managed_shared_memory.hpp> 

class FileLocker 
{ 
public: 
    FileLocker() { } 
    ~FileLocker() { } 

    // non-copyable: 
    FileLocker(FileLocker const&)    = delete; // noncopyable 
    FileLocker& operator==(FileLocker const&) = delete; // noncopyable 

    // movable 
    FileLocker(FileLocker&&) = default; 

private: 
    boost::interprocess::managed_shared_memory m_oShMem; 
    std::unique_ptr<boost::interprocess::named_mutex> m_oSetFileMutex; 
}; 

int main() { 
    FileLocker fl; 
    auto moved = std::move(fl); 
} 

Но учитывая тот факт, что managed_shared_memory является уже без копируемыми, вы могли бы использовать Rule Of Zero:

Live On Coliru

#include <memory> 
#include <boost/interprocess/sync/named_mutex.hpp> 
#include <boost/interprocess/managed_shared_memory.hpp> 

class FileLocker { 
    boost::interprocess::managed_shared_memory m_oShMem; 
    std::unique_ptr<boost::interprocess::named_mutex> m_oSetFileMutex; 
}; 

int main() { 
    FileLocker fl; 
    auto moved = std::move(fl); 

    //auto copy = moved; // doesn't compile 
} 
+0

Привет и спасибо за ответ. = delete, = default недоступны в VS 2010. Я попытался переопределить конструктор копирования, но (отрицательные) результаты остались неизменными. Тем не менее, я хочу узнать о версии &&. Я попробую включить все из них в частном разделе (старый путь) и вернуться позже! – gilgamash

+0

Нет, не работает. Также удалили вывод. Такое же сообщение об ошибке .... – gilgamash

+0

Звучит ужасно смущенным. Вот версия C++ 11-dumbed: http://coliru.stacked-crooked.com/a/98473fe0ce08ec87 – sehe

Смежные вопросы