I am trying to make a class that manipulates with Boost sockets to make the conections simple to use.
My SocketClient
class has a few properties with boost::asio::ip::tcp::socket
being one of them. But I get C2512 error in my constructor, because boost::asio::ip::tcp::socket
cannot exist unitialised, as it has no constructor.
Here, see the code of the class:
class SocketClient {
private:
int port; //Port, currently unused
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver::iterator endpoint_iterator;
boost::asio::ip::tcp::socket sock; //This causes the error
//It wants to be like this (impossible too):
//boost::asio::ip::tcp::socket sock(io_service);
public:
void init(const char*, const char* );
SocketClient(); //Default constructor
bool connect();
bool read(int bytes, char *text);
bool send(int length, char *text);
bool send(std::string text);
unsigned int timeout;
};
And here is the constructor:
SocketClient::SocketClient() { //ERROR: (23): error C2512: 'boost::asio::basic_stream_socket<Protocol>' : no appropriate default constructor available
sock=boost::asio::ip::tcp::socket(io_service); //Adding this didn't help
}
So what to do? Do I have to keep sock
as void*
?
Use initialization lists :
SocketClient::SocketClient()
:
sock(io_service)
{
// Other initialization code here...
}
Be careful though: this is well-defined because member variables are constructed in the order they appear in the class definition , and io_service
appears before sock
. If that wasn't the case, you would pass an uninitialized object to the constructor of socket
, most likely resulting in Undefined Behavior.
If you are using C++ 11, you can do it like this:
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver::iterator endpoint_iterator;
boost::asio::ip::tcp::socket sock { io_service };
But (as Andy Prowl said) io_service must be must be placed before sock in the member list.
This would compile, but may lead to unpredictable errors:
boost::asio::ip::tcp::socket sock { io_service };
boost::asio::io_service io_service;
generally - as already stated - whenever possible use initialization lists. also use a naming scheme that identifies members.
also already stated - initialization depends on member order. if you have dependencies between members this is most often a sign for a design error. it smells. at least document this well in the code - there is always a next maintainer. of course you can alway hold elements via typed (smart) pointers.
for the concrete problem I'd suggest to pass the io_service via reference. this would give you more control over the io_service (eg. use async mode and run multiple sockets within one io_service)
#include <boost/asio.hpp>
class SocketClient {
private:
boost::asio::io_service& m_io_service;
boost::asio::ip::tcp::socket m_socket;
[...]
public:
SocketClient(boost::asio::io_service& io_service);
[...]
};
SocketClient::SocketClient(boost::asio::io_service& io_service)
: m_io_service(io_service)
, m_socket(io_service)
[...]
{
}
header .h
boost::asio::ip::tcp::socket *sock;
body .cpp
sock = new boost::asio::ip::tcp::socket(service);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.