boost named_mutex私有成员访问错误

问题描述:

我患有一个问题,我需要一个名为managed_shared_memory成员在一个类内的managed_shared_memory成员,并得到“无法访问类boost :: interprocess :: named_mutex中声明的私有成员”错误。然而,我都从boost :: noncpoyable派生了我的类,并在构造函数中使用了带有移动语义的std :: unique_ptr,但没有成功。使用boost 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))); 
} 

我阅读了有关这一问题的若干#1,主题,但他们都指出我已经处理的imho的非可复制性......

感谢您的帮助!

撇开其他问题,您呼叫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

首先,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