提升named_mutex私有成员访问错误

时间:2016-03-04 12:31:37

标签: c++ boost mutex private interprocess

我遇到的问题是,我需要一个类中的managed_shared_memory成员的named_mutex,并且得到一个"无法访问类boost :: interprocess :: named_mutex"中声明的私有成员。错误。但是,我从boost :: noncpoyable派生了我的类,并在构造函数中使用了带有move-semantic的std :: unique_ptr,但没有成功。使用boost 1_60和VS 2010,代码如下:

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")() );
}

最后make-unique:

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-Threads,但是所有这些都指出了我已经处理过的不可复制性......

感谢您的帮助!

2 个答案:

答案 0 :(得分: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*作为参数。这样的构造函数不存在。

答案 1 :(得分: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
}