2

public メソッドを持つ overlay_server というクラスがあります

void member_list_server(boost::asio::io_service &io_service){

これを新しいスレッドで実行したいと思います。そこで、新しいスレッドを作成し、そのコンストラクターで bind を使用します。

void member_list_server 関数内で io_service を作成する前に。しかし、今、メインで io_service オブジェクトを作成して、エラーが発生するこのスレッドに渡そうとしていますか?

  int main(){

    boost::asio::io_service io_service_;

    overlay_server overlay_server_(8002);
    boost::thread thread_(
        boost::bind(&overlay_server::member_list_server, overlay_server_, io_service_)
        );
  1. なぜエラーが発生するのですか

    エラー C2248: 'boost::noncopyable_::noncopyable::noncopyable': クラス 'boost::noncopyable_::noncopyable' で宣言されたプライベート メンバーにアクセスできません

  2. io_service を必要とする他のクラスのインスタンスも作成します。メインで io_service オブジェクトを 1 つ作成し、それをすべてのスレッドに渡すのが最善の方法ですか?

または、将来作成するすべてのスレッド内に別のスレッドを作成しますか?

4

1 に答える 1

1

問題は、boost::asio::io_service オブジェクトを参照ではなく値で渡していることです。これは、boost::asio::io_service デフォルトのコピー コンストラクターを呼び出す必要があることを意味しますが、これは io_service では許可されていません。

1 つのオプションは、boost::asio::io_service オブジェクトへのポインターを渡すことです。以下は、まさにそれを行う私のコードです。

void Model::TcpPortListener (boost::asio::io_service &io_service, 
                             boost::asio::ip::tcp::acceptor &a, 
                             boost::asio::ip::tcp::endpoint &lep, 
                             SocketObject *readSocketObject)
{
    boost::asio::ip::tcp::acceptor *b = &a;
    boost::asio::io_service *s = &io_service;
    . . .
    boost::asio::ip::tcp::socket *sock (new boost::asio::ip::tcp::socket (io_service));

    a.async_accept (*sock, boost::bind (&Model::HandleRemoteAccept, this, s, b, sock, lep, boost::asio::placeholders::error));
}

void Model::HandleRemoteAccept (boost::asio::io_service *io_service, 
                                boost::asio::ip::tcp::acceptor *a, 
                                boost::asio::ip::tcp::socket *sock, 
                                boost::asio::ip::tcp::endpoint &lep, 
                                const boost::system::error_code& error)
{
    . . .
    // Continue listening
    TcpPortListener (*io_service, *a, lep, 0);
}

観察するポイントは次のとおりです。

  1. Model::TcpPortListener()では、's'にio_serviceのアドレスが割り当てられます
  2. 同じ関数で、's' が boost::bind() の 3 番目の引数として渡されます。これはオブジェクトではなくアドレスであるため、既定のコピー コンストラクターは呼び出されません。
  3. Model::HandleRemoteAccept() では、io_service が逆参照され、TcpPortListener() 関数に渡されます。

ダングリング参照について他の人が指摘した点は重要であり、十分に説明する必要があります。

于 2013-05-30T09:52:23.733 に答える