错误C2280:'std :: thread :: thread(const std :: thread&)':尝试引用已删除的函数

 mobiledu2502863483 发布于 2023-02-08 17:32

我在尝试创建使用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::vector clients;
    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()).

2 个回答
  • 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()).

    2023-02-08 17:34 回答
  • 一个std::thread对象是不可拷贝.调用此行时:

    clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate));
    

    StreamServerClient您创建的对象需要添加到clients向量中,但唯一的方法是复制它,因为您的StreamServer对象没有定义移动构造函数.StreamServerClient生成默认的复制构造函数,以及C++ 11中的默认复制构造函数是什么,它调用所有数据成员的复制构造函数.

    在这种情况下,它调用std::thread数据成员的复制构造函数,该构造函数将被删除.

    std::threads无法复制的原因是std::thread对象对应于执行的线程.您应该重构您的代码,IMO.你可以将移动构造函数混合在一起StreamServerClient,但我认为有更清晰的解决方案,例如,用一个完全独立的调用替换std::thread指针std::thread和初始化线程.

    编辑:一般来说,我会说在一个对象的构造函数中分支一个新线程是不明智的,因为它太精巧了.(它可能会失败,那么你必须处理异常等)尽管可能C++纯粹主义者会不同意我的看法.

    编辑:有愚蠢的术语.

    2023-02-08 17:34 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有