Невозможно сделать объект недоступным для копирования

0

Я создаю серверный интерфейс для сетевого программирования, и у меня возникла проблема. Я хочу сделать объект сервера непокрытым, главным образом потому, что на самом деле не имеет смысла это делать и, вероятно, будет создавать проблемы, а также потому, что он использует потоки, которые невозможно скопировать. Однако, когда я делаю оператор-конструктор копирования и оператор присваивания закрытым, я получаю сообщение об ошибке:

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?

В любом случае, это, спасибо за ваше время

Обновить

Поэтому я добавил a = 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>          ]

Строка 19 в Server.h которой упоминается, является объявлением конструктора копирования. Строка 94 в Server.cpp - это создание потоков:

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

Функция acceptConnections берет сервер по постоянной ссылке, поэтому он не должен копировать, вот объявление:

friend void acceptConnections(const Server&);
  • 0
    Отправляемая ошибка выглядит как нечто, скопированное из окна «Ошибки» Visual Studio. Это правильно? Если это так, вы можете захотеть взглянуть на окно «Вывод» (в частности, сборку вывода), которое иногда предоставляет немного больше деталей.
  • 0
    Да, я дам вам окно вывода, всего на секунду
Показать ещё 8 комментариев
Теги:
copy

1 ответ

4
Лучший ответ

Ваша проблема наиболее вероятна в конструкторе потоков:

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

Попробуйте это вместо этого:

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

потому что без оболочки std :: ref() копия экземпляра сервера будет передана в конструктор потока, который, в свою очередь, передаст эту копию по ссылке на ваш метод acceptConnections(). Или, по крайней мере, попытаться, но он так и не дошел, поскольку компилятор не смог выполнить первоначальную копию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню