我在尝试创建使用C++ 11标准线程的VC++静态库时遇到问题.
我目前有两个类,我能够声明并稍后在我的起始类(最后声明的)上定义一个线程.在此阶段,代码只是一个套接字侦听器,然后创建另一个类的对象来处理接受的每个客户端.这些子对象应该创建并行数据捕获,编码和传输所需的线程.
问题是:如果我在我的另一个类上声明一个std :: thread,即使我完全像在我的start类上那样,无论如何,我在构建时遇到这个错误 error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function [...]\vc\include\functional 1124 1
我能够解决这个错误的唯一方法是std::thread
根据我想要它做的事情,根本不在后一个类中声明一个对象,这是不可能的.
我正在使用VS2013,我的来源是:
stdafx.h中
#pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include#include #include #include #include #include
StreamServer.h
#pragma once #define DEFAULT_BUFLEN 65535 #define DEFAULT_PORT "5649" class StreamServerClient { public: bool* terminate; //std::thread client; //If I comment this line out, it builds just fine. void DoNothing(); StreamServerClient(SOCKET clientSock, bool* ptTerm); StreamServerClient(); ~StreamServerClient(); }; class StreamServer { public: bool terminate; std::thread Listener; std::vectorclients; void CreateClient(SOCKET, bool*); void Listen(); StreamServer(); ~StreamServer(); };
StreamServer.cpp
#include "stdafx.h" #include "StreamServer.h" StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm) { terminate = ptTerm; //client = std::thread(&StreamServerClient::DoNothing, this); //Same thing as the declaration } StreamServerClient::StreamServerClient() { *terminate = false; //client = std::thread(&StreamServerClient::DoNothing, this); //Same thing as the declaration } void StreamServerClient::DoNothing() { } StreamServerClient::~StreamServerClient() { } void StreamServer::Listen() { {...} do { clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate)); std::cout << "accepted a client!" << std::endl; } while (!terminate); } StreamServer::StreamServer() { terminate = false; Listener = std::thread(&StreamServer::Listen, this); Listener.detach(); } StreamServer::~StreamServer() { }
Dietmar Kühl.. 11
std::thread
无法复制类型的对象.您最好只是初始化成员初始化列表中的对象:
class StreamServerClient { public: bool* terminate; std::thread client; void DoNothing(); StreamServerClient(SOCKET clientSock, bool* ptTerm); StreamServerClient(StreamServerClient&& other); ~StreamServerClient(); }; StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm) : terminate(ptTerm) , client(std::thread(&StreamServerClient::DoNothing, this)) { } StreamServerClient::StreamServerClient(StreamServerClient&& other) : terminate(other.terminate) , client(std::move(other.client)) { }
我省略了默认构造函数(请注意,您的版本不起作用,因为它试图为取消引用未初始化指针的结果赋值),而是添加了一个移动构造函数:std::vector<...>
当提供某些内容时,将推回到此构造函数时看起来像一个临时的东西(即,某些东西是临时的或者看起来像是一个,例如,使用std::move()
).
std::thread
无法复制类型的对象.您最好只是初始化成员初始化列表中的对象:
class StreamServerClient { public: bool* terminate; std::thread client; void DoNothing(); StreamServerClient(SOCKET clientSock, bool* ptTerm); StreamServerClient(StreamServerClient&& other); ~StreamServerClient(); }; StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm) : terminate(ptTerm) , client(std::thread(&StreamServerClient::DoNothing, this)) { } StreamServerClient::StreamServerClient(StreamServerClient&& other) : terminate(other.terminate) , client(std::move(other.client)) { }
我省略了默认构造函数(请注意,您的版本不起作用,因为它试图为取消引用未初始化指针的结果赋值),而是添加了一个移动构造函数:std::vector<...>
当提供某些内容时,将推回到此构造函数时看起来像一个临时的东西(即,某些东西是临时的或者看起来像是一个,例如,使用std::move()
).
一个std::thread
对象是不可拷贝.调用此行时:
clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate));
StreamServerClient
您创建的对象需要添加到clients
向量中,但唯一的方法是复制它,因为您的StreamServer
对象没有定义移动构造函数.StreamServerClient
生成默认的复制构造函数,以及C++ 11中的默认复制构造函数是什么,它调用所有数据成员的复制构造函数.
在这种情况下,它调用std::thread
数据成员的复制构造函数,该构造函数将被删除.
std::thread
s无法复制的原因是std::thread
对象对应于执行的线程.您应该重构您的代码,IMO.你可以将移动构造函数混合在一起StreamServerClient
,但我认为有更清晰的解决方案,例如,用一个完全独立的调用替换std::thread
指针std::thread
和初始化线程.
编辑:一般来说,我会说在一个对象的构造函数中分支一个新线程是不明智的,因为它太精巧了.(它可能会失败,那么你必须处理异常等)尽管可能C++纯粹主义者会不同意我的看法.
编辑:有愚蠢的术语.