C++ Boost ASIO:在类中初始化 io_context:

Posted

技术标签:

【中文标题】C++ Boost ASIO:在类中初始化 io_context:【英文标题】:C++ Boost ASIO: initializing io_context inside class: 【发布时间】:2018-03-12 21:11:03 【问题描述】:

我正在关注 Boost UDP 多播发送者教程here .我将其修改为如下所示的类:

#define _CRT_SECURE_NO_WARNINGS
#include <ctime>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
using boost::asio::ip::udp;
using std::cout;
using std::cin;
using std::endl;

class sender

private:
    boost::asio::io_context io_context;
    boost::asio::ip::udp::endpoint endpoint_;
    boost::asio::ip::udp::socket socket_;
    int message_count_;
    std::string message_;
    bool showBroadcast;

public:
    // constructor
    sender(std::string multicast_address, unsigned short multicast_port, bool show = true)
    
        boost::asio::io_context io_context;
        boost::asio::ip::udp::endpoint endpoint_(boost::asio::ip::make_address("192.168.0.255"), 13000);
        boost::asio::ip::udp::socket socket_(io_context, endpoint_.protocol());
        socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));  // no need
    

    // destructor
    ~sender()
    
        cout << "UDP sender exiting." << endl;
    

private:
    std::string get_input()
    
        std::string result;
        cout << "Enter your message: ";
        getline(cin, result);
        return result;
    

    std::string make_daytime_string()
    
        using namespace std; // For time_t, time and ctime;
        time_t now = time(0);
        std::string result = ctime(&now);
        return result.erase(result.length() - 1, 1);
    

    std::string some_string()
    
        std::string result;
        result = make_daytime_string();
        return result;
    
;

int main(int argc, char* argv[])

    try
    
        sender s("192.168.0.255", 13000);
    
    catch (std::exception& e)
    
        std::cerr << "Exception: " << e.what() << "\n";
    

    return 0;

我希望将 io_context 对象封装在类中,而不是将它放在外面。 VC++ 抱怨:

boost::asio::basic_datagram_socket': 没有合适的默认构造函数可用

我相信它试图强迫我拥有如下的构造函数(我试图远离它):

    sender(boost::asio::io_context& io_context, const boost::asio::ip::address& multicast_address, unsigned short multicast_port, bool show = true) 
    : endpoint_(multicast_address, multicast_port),
    socket_(io_context, endpoint_.protocol())

我怎么可能将所有内容都封装在我的班级中?为什么 Boost 强迫我做相反的事情?请帮忙。非常感谢。

这似乎是由于 io_context 是不可复制的,正如建议的 here .我希望这个类可以复制。有什么想法吗?

【问题讨论】:

【参考方案1】:

没有一个 ASIO 类是可复制的,并且大多数都持有一个 io_context 引用,因此需要用一个来构造。如果您希望您的类是可复制的,您需要使用指向 ASIO 对象的共享指针。我不确定您为什么要复制 ASIO 对象,因为无论如何您一次不能从多个地方使用它们。

【讨论】:

如何初始化一个 io_service/io_context 对象并继续在同一个类中重复使用它?我看了 Sehe 的例子,不太明白如何从那里开始。 如果它是共享的,我该如何正确处理该对象? 这是否意味着我必须这样使用它? boost::shared_ptr<:asio::ip::udp::socket> 套接字; boost::shared_ptr<:asio::io_service> 服务; 您可以使用来自多个类的 io_context 但共享套接字没有多大意义。您可以静态/延迟初始化类中的上下文,以便在对象之间共享一个实例。虽然在发送者类之外创建单个上下文并将其传递给所有实例要容易得多 @muusbolla 不,OP 没有这个问题。注意你的编译器警告,这可能是 contextsocket 的初始化顺序错误,确保 contextsocket 之前声明。

以上是关于C++ Boost ASIO:在类中初始化 io_context:的主要内容,如果未能解决你的问题,请参考以下文章

C++ boost::asio::io_service创建线程池thread_group简单实例

C++ boost::asio::io_service创建线程池thread_group简单实例

C++ Boost,在类中使用 thread_group

C++ - 几个 Boost.Asio 相关问题

C++——boost:asio的使用

C++ 提升 asio 多线程