我正在为网络编程制作服务器界面,但我遇到了一个问题。我想让服务器对象不可复制,主要是因为这样做并没有意义,并且可能会产生问题,还因为它使用了无法复制的线程。但是,当我将复制构造函数和赋值运算符设为私有时,我收到错误:
Error 2 error C2248: '(namespaces..)::Server::Server' : cannot access private member declared in class '(namespaces..)::Server' (path..)\type_traits 1545 1 Server
错误似乎出现在type_traits
文件中?我根本没有使用它,虽然我可能包含的其他一些std
文件可能会使用它吗?我正在使用iostream, sstream, string, thread, map
。
这是服务器类定义:
class DLL_PUBLIC Server
{
public:
Server(unsigned int);
~Server();
(...)
private:
class PvtImpl; //Private implementation, so it isn't seen in the header file
PvtImpl *pvtImpl;
Server(const Server &par_other){}
Server& operator=(const Server &par_other){ return *this; }
(...)
};
和私人实施:
class Server::PvtImpl
{
public:
bool running;
unsigned int port, backlog, currentlyConnected;
SOCKET listenSocket;
std::thread *acceptConnectionsThread;
std::thread* *receiveDataThreads; //I am using pointers instead of vectors because I want it to be fixed
ClientObj* *clients;
std::map<ClientObj*, unsigned int> clientIndexMap;
};
由于我不知道要发布什么代码,因为我甚至不知道错误来自何处,请告诉我您是否需要发布其中的特定部分。如果我注释掉私有拷贝构造函数和赋值运算符然后它可以工作,但我不希望它是可复制的,尤其不是通过默认构造函数。怀疑它,但它与它是一个DLL有关吗?
无论如何就是这样,谢谢你的时间
更新
所以我按照建议在构造函数中添加了= delete
,并将其公开:
class DLL_PUBLIC Server
{
public:
Server(unsigned int);
Server(const Server &par_other) = delete;
~Server();
Server& operator=(const Server &par_other) = delete;
(...)
};
我现在得到了一些不同的错误,但也在type_traits文件中:
Error 2 error C2280: '(namespaces..)::Server::Server(const (namespaces..)::Server &)' : attempting to reference a deleted function (path..)\type_traits 1545 1 Server
在该文件中抱怨的一些代码:
// TEMPLATE FUNCTION _Decay_copy
template<class _Ty> inline
typename decay<_Ty>::type _Decay_copy(_Ty&& _Arg)
{ // forward _Arg as value of decayed type
return (_STD forward<_Ty>(_Arg));
}
_STD_END
更新2
所以这是VS的输出窗口:
1>(path...)\type_traits(1545): error C2280: '(namespaces..)::Server::Server(const (namespaces..)::Server &)' : attempting to reference a deleted function
1> (path..)\Server.h(19) : see declaration of '(namespaces..)::Server::Server'
1> (path..)\thread(47) : see reference to function template instantiation '(namespaces..)::Server std::_Decay_copy<(namespaces..)::Server&>(_Ty)' being compiled
1> with
1> [
1> _Ty=(namespaces..)::Server &
1> ]
1> Server.cpp(94) : see reference to function template instantiation 'std::thread::thread<void(__cdecl &)(const (namespaces..)::Server &),(namespaces..)::Server&>(_Fn,(namespaces..)::Server &)' being compiled
1> with
1> [
1> _Fn=void (__cdecl &)(const (namespaces..)::Server &)
1> ]
它提到的Server.h
中的第19行是复制构造函数声明。 Server.cpp
中的第94行是线程创建:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);
acceptConnections
函数通过常量引用获取服务器,因此它不应该复制,这是声明:
friend void acceptConnections(const Server&);
答案 0 :(得分:4)
您的问题很可能出现在线程构造函数中:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);
请改为尝试:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, std::ref(*this));
因为没有std :: ref()包装器,服务器实例的副本将被传递给线程构造函数,而线程构造函数又通过引用传递给acceptConnections()方法。或者至少尝试,但它从来没有那么远,因为编译器未能通过初始拷贝。