Почему сокеты sfml не работают внутри класса?

Вчера пол вечера убил на написание класса ServerManager, который бы обрабатывал входящие сообщения и подключения. Всё было написано в абсолютном соответствии с документацией sfml, однако происходило вот что: после первого подключения и добавления этого подключения в SocketSelector сервер переставал принимать вообще какие-либо сигналы, т.е. невозможно было ни повторно подключиться, ни написать сообщение, метод wait просто не сигнализировал о наличии сокетов, готовых к передаче сообщения. Listener как-будто бы тоже не слышал новые подключения после самого первого из них. Я не мог понять, в чём проблема. Сейчас вот решил ради интереса переписать в примитивном виде эту логику в цикл while() внутри main`а, и... Всё работает, как надо, селектор сигнализирует о наличии новых подключений или сообщений, всё обрабатывается. Хотя логика, повторюсь, идентична тому, что написано в классе. И я всё же нашёл то самое ключевое различие: внутри класса я храню не vector sockets, а vector users, где User - мой класс, внутри которого - имя юзера и TcpSocket* socket; Т.е. фактически, тоже самое, что в первом случае, но внутри класса User, в котором дополнительно лежит имя. В первом случае - прекрасная работа, во втором - селектор просто ничего не ловит. Приведу два примера кода, первый - где, всё работает (с вектором указателей), второй - где проходит лишь первое подключение, а дальше - тишина:

Рабочий вариант с вектором TcpSocket*

while (true)
{
    if (selector.wait())
    {
        if (selector.isReady(listener)) //Поключение
        {
            TcpSocket *socket = new TcpSocket;
            listener.accept(*socket);

            Packet packet;
            socket->receive(packet);
            string str;
            packet >> str;

            cout << "NAME: " << str << endl;

            sockets.push_back(socket);
            selector.add(*socket);
        }

        else
        {
            for (auto & var : sockets)
            {
                if (selector.isReady(*var)) //Приём сообщений
                {
                    Packet packet;
                    var->receive(packet);
                    string str;
                    packet >> str;
                    cout << "MSG: " + str << endl;
                }
            }
        }
    }
}

С классом User

while (true)
{
    if (selector.wait())
    {
        if (selector.isReady(listener))
        {
            TcpSocket *socket = new TcpSocket;
            listener.accept(*socket);

            Packet packet;
            socket->receive(packet);
            string str;
            packet >> str;

            cout << "NAME: " << str << endl;

            User user = User(str, socket); //Создаём нового User (str - имя, socket указатель)
            users.push_back(user);
            selector.add(*user.getUserSocket()); //getUserSocket возвращает указатель на socket
        }

        else
        {
            for (auto & var : users)
            {
                if (selector.isReady(*var.getUserSocket()))
                {
                    Packet packet;
                    var.getUserSocket()->receive(packet);
                    string str;
                    packet >> str;
                    cout << "MSG: " + str << endl;
                }
            }
        }
    }
}

Скажите, пожалуйста, в чём дело? Как это обойти?


Ответы (1 шт):

Автор решения: GRUB_666

Приношу свои извинения, буквально после того, как я задал вопрос, мне удалось найти проблему: Внутри первого блока if (см. 2 пример) происходит создание промежуточной сущности user, которая, хранит указатель на новый сокет. Трагедия в том, что как только блок завершается, сущность уничтожается, вызывается деструктор, который очищает указатель на socket, в связи с чем внутри selector`а образуется мусор, с которым он, само собой, работать не может. Удаление delete socket исправило проблему

→ Ссылка