代码之家  ›  专栏  ›  技术社区  ›  kakyo

在类中包含zmq::socket成员的正确方法是什么?

  •  0
  • kakyo  · 技术社区  · 5 年前

    对于Visual Studio 2017,由于已删除构造函数,以下代码无法编译

    
    // MyClass.h
    
    #include <zmq.hpp>
    
    extern zmq::context_t g_context;
    
    class MyCppZMQClass
    {
    public:
        MyCppZMQClass();
        ~MyCppZMQClass();
    
    private:
        zmq::socket_t m_socket;
    };
    
    
    //  MyClass.cpp
    
    #include "MyCppZMQClass.h"
    
    zmq::context_t g_context = zmq::context_t(1);
    
    
    MyCppZMQClass::MyCppZMQClass()
        :m_socket(g_context, zmq::socket_type::sub)
    {
    }
    
    
    MyCppZMQClass::~MyCppZMQClass()
    {
    }
    

    主CPP

    // hello_cpp.cpp
    
    #include "MyCppZMQClass.h"
    
    int main()
    {
        auto mc = MyCppZMQClass();
    }
    

    编译器错误:

    1>g:\\hello_cpp\hello_cpp.cpp(73): error C2280: 'MyCppZMQClass::MyCppZMQClass(const MyCppZMQClass &)': attempting to reference a deleted function
    1>g:\hello_cpp\mycppzmqclass.h(15): note: compiler has generated 'MyCppZMQClass::MyCppZMQClass' here
    1>g:\hello_cpp\mycppzmqclass.h(15): note: 'MyCppZMQClass::MyCppZMQClass(const MyCppZMQClass &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'zmq::socket_t::socket_t(const zmq::socket_t &)'
    1>e:\_dev\vcpkg\installed\x64-windows\include\zmq.hpp(1513): note: 'zmq::socket_t::socket_t(const zmq::socket_t &)': function was explicitly deleted
    

    我查过了我叫这个

    // zmq.hpp
    
    #ifdef ZMQ_CPP11
        socket_t(context_t &context_, socket_type type_)
            : socket_t(context_, static_cast<int>(type_))
        {
        }
    #endif
    

    ZMQ_CPP11 定义为VS2017

    // zmq.hpp
    
    #if (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1900)
        #define ZMQ_CPP11
    #endif
    

    但是,在主函数中实例化套接字对象会编译。

    int main()
    {
        zmq::context_t ctx;
        zmq::socket_t sock(ctx, zmq::socket_type::push);
        sock.bind("inproc://test");
        std::string m = "Hello, world";
        sock.send(zmq::buffer(m), zmq::send_flags::dontwait);
    }
    

    我错过了什么?

    在以前的情况下,我应该使用哪个构造函数?

    更新

    如果删除复制构造函数和运算符=,则问题仍然存在。

    #include <zmq.hpp>
    
    extern zmq::context_t g_context;
    
    class MyCppZMQClass
    {
    public:
        MyCppZMQClass();
        ~MyCppZMQClass();
    
        MyCppZMQClass(const MyCppZMQClass&) = delete;
        MyCppZMQClass& operator=(const MyCppZMQClass&) = delete;
    
    private:
        zmq::socket_t m_socket;
    };
    
    2 回复  |  直到 5 年前
        1
  •  1
  •   n. m. could be an AI    5 年前
    auto mc = MyCppZMQClass();
    

    在这里,您试图创建一个临时的,然后使用复制构造函数初始化一个变量。改为

    MyCppZMQClass mc;
    

    或者添加一个移动构造函数/赋值。

        2
  •  1
  •   yumetodo    5 年前

    将复制构造函数和运算符标记为已删除

    这是解决这个问题的正确方法。

    mycppzmqclass现在不请求copy constructible或copy assignable。

    不要忘记提供move-ctor/assign-op。