将 zmq::socket_t 成员包含在 class 中的正确方法?
The right way to include a zmq::socket_t member in a class?
对于 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;
};
mark copy constructor and operator = as deleted
这才是解决这个问题的正确方法。
MyCppZMQClass 现在不请求可复制构造或可复制分配。
不要忘记提供移动 ctor/assign 操作。
auto mc = MyCppZMQClass();
在这里您尝试创建一个临时变量,然后使用复制构造函数从中初始化一个变量。改为
MyCppZMQClass mc;
或加步constructor/assignment.
对于 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;
};
mark copy constructor and operator = as deleted
这才是解决这个问题的正确方法。
MyCppZMQClass 现在不请求可复制构造或可复制分配。
不要忘记提供移动 ctor/assign 操作。
auto mc = MyCppZMQClass();
在这里您尝试创建一个临时变量,然后使用复制构造函数从中初始化一个变量。改为
MyCppZMQClass mc;
或加步constructor/assignment.