3

I have class where I use boost asio library:

Header:

class TestIOService {

public:
    void makeConnection();
    static TestIOService getInst();

private:
    TestIOService(std::string address);
    std::string address;
    // boost::asio::io_service service;
};

Impl:

#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/udp.hpp>
#include "TestIOService.h"

void TestIOService::makeConnection() {
    boost::asio::io_service service;
    boost::asio::ip::udp::socket socket(service);
    boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string("192.168.1.2"), 1234);
    socket.connect(endpoint);
    socket.close();
}

TestIOService::TestIOService(std::string address) : address(address) { }

TestIOService TestIOService::getInst() {
    return TestIOService("192.168.1.2");
}

And main:

int main(void)
{
    TestIOService service = TestIOService::getInst();
    service.makeConnection();
}

When I have service defined in makeConnection method with this line:

boost::asio::io_service service;

there is no problem, but when I have it as class field member(commented out in code) I get this error:

note: ‘TestIOService::TestIOService(TestIOService&&)’ is implicitly deleted because the default definition would be ill-formed: class TestIOService {

Joe
  • 1,270
  • 2
  • 17
  • 24

1 Answers1

5

io_service is not copyable.

You can make it shared quickly by wrapping it in shared_ptr<io_service>, but you should really reconsider the design first.

If your class needs to be copyable, it would logically not contain the io_service object

E.g. the following sample does create two instances of the test class not sharing a connection:

Live On Coliru

#include <boost/asio.hpp>
#include <boost/make_shared.hpp>
#include <iostream>

class TestIOService {

public:
    void makeConnection();
    static TestIOService getInst();

private:
    TestIOService(std::string address);
    std::string address;

    boost::shared_ptr<boost::asio::ip::udp::socket> socket;
    boost::shared_ptr<boost::asio::io_service> service;
};

void TestIOService::makeConnection() {
    using namespace boost::asio;
    service = boost::make_shared<io_service>();
    socket  = boost::make_shared<ip::udp::socket>(*service);
    socket->connect({ip::address::from_string("192.168.1.2"), 1234 });
    //socket->close();
}

TestIOService::TestIOService(std::string address) 
    : address(address) { }

TestIOService TestIOService::getInst() {
    return TestIOService("192.168.1.2");
}

int main() {
    auto test1 = TestIOService::getInst();
    auto test2 = TestIOService::getInst();
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks for answer, I am not very skilled in c++ but about that design should I create new io_service for every new request? – Joe Apr 14 '15 at 09:53
  • The shared pointer would do, as long you'd call `getInst()` each time. Just copying the class won't create a new io_service though (note that _returning_ from `getInst()` tries to copy (or move) the class) – sehe Apr 14 '15 at 09:54
  • @Joe expanded with a helpful (?) example *[Live On Coliru](http://coliru.stacked-crooked.com/a/f219f1396a36cae8)* – sehe Apr 14 '15 at 10:00
  • That example was really helpful, it works smoothly, about that shared_ptrs do I need to call any delete on them or are they allocated on stack? – Joe Apr 14 '15 at 10:42
  • [False dichotomy](http://en.wikipedia.org/wiki/False_dichotomy): They're not allocated on the stack an you don't need to call any delete on them. Also, most standard library features have documentation, as you would expect: http://en.cppreference.com/w/cpp/memory/shared_ptr – sehe Apr 14 '15 at 11:32
  • I have problem using io_service.run method(example here: http://coliru.stacked-crooked.com/a/ed736ccf8c57395a ) There is operation1 and operation2 first executes ok but in second the callback is not called, I looked into wireshark and response is made. Is there error in code or something else? – Joe Apr 15 '15 at 08:45
  • Probably because `run()` exited. Look at http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/io_service__work.html. **Edit** Or http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/io_service/reset.html – sehe Apr 15 '15 at 08:49
  • Question: is the `service = boost::make_shared();` in `makeConnection()` really necessary? Isn't an `io_service` object already created by the default constructor? – GregPhil Aug 07 '16 at 17:29