【问题标题】:boost named_mutex private member access errorboost named_mutex 私有成员访问错误
【发布时间】:2016-03-04 12:31:37
【问题描述】:

我遇到了一个问题,即我需要为类中的 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")() );
}

最后是独一无二的:

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,但他们都指出了我处理过的不可复制性......

感谢您的帮助!

【问题讨论】:

    标签: c++ boost mutex private interprocess


    【解决方案1】:

    撇开其他问题不谈,您在两个地方错误地调用了 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* 作为参数。不存在这样的构造函数。

    【讨论】:

    • 啊。我什至没有看到发现或构造。这可能会帮助 OP 找出它缺失的部分。 +1
    • 非常感谢您提供此信息,我会在回到问题后立即尝试(星期一)!
    • 尽管您将互斥锁名称放在共享内存位置,但您的回答绝对正确并有助于解决问题。谢谢!
    【解决方案2】:

    首先,boost::noncopyable 是不可移动的。因此,除非您编写自定义移动构造函数/赋值(五规则),否则您将永远不会获得可移动类型。如果基数不可移动,编译器无法生成默认的移动特殊成员。

    这是天真的固定类:

    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
    }
    

    【讨论】:

    • 您好,感谢您的回答。 =delete, =default 在 VS 2010 中不可用。我尝试重新实现复制构造函数,但(负)结果保持不变。但是,我对 && 版本感到困惑。我会尝试将所有这些都包含在私人部分(旧方式)中,然后再回来!
    • 你听起来非常困惑。这是 c++11 哑版本:coliru.stacked-crooked.com/a/98473fe0ce08ec87
    • 不,我不困惑。我只是忘记了我添加的 = 运算符的 && 版本(基本上与您的建议相同,但在 cpp 文件中实现)。 “无法访问私人成员”错误仍然出现。
    猜你喜欢
    • 2012-05-13
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多