无法使对象不可复制

时间:2014-12-06 15:22:29

标签: c++ copy

我正在为网络编程制作服务器界面,但我遇到了一个问题。我想让服务器对象不可复制,主要是因为这样做并没有意义,并且可能会产生问题,还因为它使用了无法复制的线程。但是,当我将复制构造函数和赋值运算符设为私有时,我收到错误:

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&);

1 个答案:

答案 0 :(得分:4)

您的问题很可能出现在线程构造函数中:

pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);

请改为尝试:

pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, std::ref(*this));

因为没有std :: ref()包装器,服务器实例的副本将被传递给线程构造函数,而线程构造函数又通过引用传递给acceptConnections()方法。或者至少尝试,但它从来没有那么远,因为编译器未能通过初始拷贝。