C++ Can';不要在构造函数中使用boost.asio解析器
我有一个类,其属性定义如下:C++ Can';不要在构造函数中使用boost.asio解析器,c++,sockets,boost,tcp,boost-asio,C++,Sockets,Boost,Tcp,Boost Asio,我有一个类,其属性定义如下: private: const std::string m_ip; bool is_connected; boost::asio::io_service m_io_service; tcp::resolver m_resolver; tcp::resolver::query m_query; tcp::resolver::iterator m_endpoint_iterator; tcp::socket m_so
private:
const std::string m_ip;
bool is_connected;
boost::asio::io_service m_io_service;
tcp::resolver m_resolver;
tcp::resolver::query m_query;
tcp::resolver::iterator m_endpoint_iterator;
tcp::socket m_socket;
//I changed this to const& because, while Copy Ellision *might* optimize this, it's still
//more semantically correct to pass by const reference.
Connection::Connection(const std::string & ip)
: m_ip(ip)
, is_connected(false)
//Note that we're no longer referring to the underlying type.
, m_resolver(m_io_service)
, m_query(m_ip, "connect_back")
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(m_io_service)
{}
以及构造函数实现,我定义如下:
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
在这里,在构造函数中,我定义了几乎所有需要定义的属性
但是我有一个在完整的.cpp
文件中从未遇到过的问题:当我在构造函数中定义解析器时,编译器说我有一个错误:
/home/User/C++ Projects/Client/Network.cpp:9: error: no matching function for call to ‘boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::basic_resolver(boost::asio::io_service*)’
Connection::Connection(const std::string ip) : m_ip(ip), is_connected(false), m_resolver(tcp::resolver(&m_io_service)), m_query(tcp::resolver::query(m_ip, "connect_back")), m_endpoint_iterator(m_resolver.resolve(m_query)), m_socket(tcp::socket(m_io_service)){
^
及
/usr/include/boost/asio/ip/basic_解析器。hpp:44:错误:'boost::asio::basic_io_对象::basic_io_对象(const boost::asio::basic_io_对象&)[带IoObjectService=boost::asio::ip::resolver_服务;bool Movable=false]'在此上下文中是私有的
forboost::asio::ip::basic\u解析器
通过引用接受参数:
basic_resolver(boost::asio::io_service& io_service)
您已经获取了变量的地址并传递了一个指针:
m_resolver(tcp::resolver(&m_io_service))
尝试删除&
forboost::asio::ip::basic\u解析器
通过引用接受参数:
basic_resolver(boost::asio::io_service& io_service)
您已经获取了变量的地址并传递了一个指针:
m_resolver(tcp::resolver(&m_io_service))
尝试删除
&
添加到@Muscampester的答案中,看起来您的构造函数是多余的
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
应该这样写:
private:
const std::string m_ip;
bool is_connected;
boost::asio::io_service m_io_service;
tcp::resolver m_resolver;
tcp::resolver::query m_query;
tcp::resolver::iterator m_endpoint_iterator;
tcp::socket m_socket;
//I changed this to const& because, while Copy Ellision *might* optimize this, it's still
//more semantically correct to pass by const reference.
Connection::Connection(const std::string & ip)
: m_ip(ip)
, is_connected(false)
//Note that we're no longer referring to the underlying type.
, m_resolver(m_io_service)
, m_query(m_ip, "connect_back")
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(m_io_service)
{}
不同之处在于,解析程序、查询和套接字对象不再是“移动构造”,而是直接构造。根据您遇到的第二个错误,看起来您使用的是boost版本,其中这些对象不可移动/移动可构造(或者boost可能从未打算让这些类型可移动;不确定是哪一个)
如果您使用的是旧版本的boost,请尝试更新到库的更高版本。但是,不管你是否这样做,你都需要更新代码,这样你就不会再不必要地移动构造了。在@Muscampester的答案中添加,看起来你的构造函数是多余的
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
应该这样写:
private:
const std::string m_ip;
bool is_connected;
boost::asio::io_service m_io_service;
tcp::resolver m_resolver;
tcp::resolver::query m_query;
tcp::resolver::iterator m_endpoint_iterator;
tcp::socket m_socket;
//I changed this to const& because, while Copy Ellision *might* optimize this, it's still
//more semantically correct to pass by const reference.
Connection::Connection(const std::string & ip)
: m_ip(ip)
, is_connected(false)
//Note that we're no longer referring to the underlying type.
, m_resolver(m_io_service)
, m_query(m_ip, "connect_back")
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(m_io_service)
{}
不同之处在于,解析程序、查询和套接字对象不再是“移动构造”,而是直接构造。根据您遇到的第二个错误,看起来您使用的是boost版本,其中这些对象不可移动/移动可构造(或者boost可能从未打算让这些类型可移动;不确定是哪一个)
如果您使用的是旧版本的boost,请尝试更新到库的更高版本。但是,不管您是否这样做,您都需要更新代码,这样您就不会再不必要地移动构建了。很好。这就解释了所有与移动相关的错误,因为它只传递了右值。@minage您必须澄清您的意思。我展示的代码没有考虑到哪些“属性”是你试图避免的?我已经使用了Boost的最新版本,我使用了你展示的代码,它使用了对ip的引用,但它仍然不起作用。我在移动构造函数方面没有问题,但有一个错误:调用“boost::asio::ip::basic_resolver::basic_resolver(boost::asio::io_service*)”@Minege我修复了代码。我忘了删除错误使用
&
来获取m_io_服务
的地址,@Muscampester的回答讨论了这个问题。好极了!它在工作:)!谢谢现在,我真的不明白为什么它比我的第一个代码主张工作得更好。通过引用接收IP参数,不再引用底层类型,但为什么这样做效果更好?因为您直接从对象调用构造函数?你能不能像你说的那样给我一些关于“搬家建筑”的链接?因为这似乎就是诀窍!谢谢抢手货这就解释了所有与移动相关的错误,因为它只传递了右值。@minage您必须澄清您的意思。我展示的代码没有考虑到哪些“属性”是你试图避免的?我已经使用了Boost的最新版本,我使用了你展示的代码,它使用了对ip的引用,但它仍然不起作用。我在移动构造函数方面没有问题,但有一个错误:调用“boost::asio::ip::basic_resolver::basic_resolver(boost::asio::io_service*)”@Minege我修复了代码。我忘了删除错误使用&
来获取m_io_服务
的地址,@Muscampester的回答讨论了这个问题。好极了!它在工作:)!谢谢现在,我真的不明白为什么它比我的第一个代码主张工作得更好。通过引用接收IP参数,不再引用底层类型,但为什么这样做效果更好?因为您直接从对象调用构造函数?你能不能像你说的那样给我一些关于“搬家建筑”的链接?因为这似乎就是诀窍!谢谢您真的不希望每个连接都有一个io_服务。它们都应该共享相同的io_服务引用,其生命周期应该比它们都长。否则,您将需要每个连接一个线程,您也不必为asio操心……好的,谢谢您的建议。我将相应地更改我的类。您真的不希望每个连接都有一个io_服务。它们都应该共享相同的io_服务引用,其生命周期应该比它们都长。否则,您将需要每个连接一个线程,您也不必为asio操心……好的,谢谢您的建议。我将相应地改变我的班级。