繁体   English   中英

如何不隐式删除默认运算符?

[英]How to not implicitly delete default operators?

我正在处理的代码产生多个线程,每个线程执行相同的一组明确定义的任务。 那些定义明确的任务可以很好地分成模块,这是我在 ATM 上失败的地方。

我有一个记录器 class 被实例化和初始化

class TLogger
{
    int SlotID{};
    States& State;
public:
    void Init(int SlotID, States& State);
    void Log(string Line);
    void LogState();
};

原因是所有记录器都写入同一个日志,因此我也需要 SlotID 来写入日志。 只要该特定线程运行,它就是不可变的。 state 也需要记录,但它是可变的。 它被线程 function (它创建并初始化它自己的记录器)突变。

我正在尝试创建一个在同一线程中运行并访问硬件的 HAL 实例。 需要记录这些访问,因此我想为在当前线程中运行的 HAL 实例提供对该线程记录器的引用

class THAL
{
    nHandle HardwareHandle;
    TLogger& OwnLogger;
public:
    void Init(nHandle HardwareHandle, TLogger& Logger);
};

void THAL::Init(nHandle HardwareHandle, TLogger& Logger)
{
    this->HardwareHandle= HardwareHandle;
    this->OwnLogger = Logger;
}

编译器说

'TLogger &TLogger::operator =(const TLogger &)': attempting to reference a deleted function
compiler has generated 'TLogger::operator =' here
'TLogger &TLogger::operator =(const TLogger &)': function was implicitly deleted because 'TLogger' has a data member 'TLogger::State' of reference type (compiling source file THAL.cpp)
see declaration of 'TLogger::State' (compiling source file THAL.cpp)

如果我没看错,编译器通过给我的 class 得到一个 =-operator 来做几乎正确的事情,但之后会杀死它。

除了切换到原始指针之外,我如何才能将线程本地记录器的引用引用到线程本地 HAL 中?

如果我只有一个线程,我会将所有内容声明为 static 单例并收工,但唉,这不是一个具有可选边界条件的爱好项目。

正如我所看到的,除了问题中提到的问题之外,您当前的代码还有另一个问题。 TLogger也不能有默认构造函数,因为非静态引用成员不能用默认构造函数初始化。 我看到解决此问题的一种方法是将Init()功能移动到类的构造函数(应该在使用之前初始化对象)并使用成员初始化器列表,如下所示:

#include <iostream>
#include <memory>
#include <string>
#include <thread>

class States{
    const static size_t SIZE = 1<<20;
    int a[SIZE];
    int dataLoad_ = 0;
    public:
    void setData(int x);
};

void States::setData(int x) {
    if(dataLoad_ < SIZE - 1) {
        a[dataLoad_++] = x;
    }
}

class TLogger
{
    size_t SlotID_ {};
    States& State_;
public:
    TLogger(int SlotID, States& State);
    void Log(std::string Line);
    void LogState();
};

TLogger::TLogger(int SlotID, States& State):
SlotID_(SlotID),State_(State)
{}

void TLogger::Log(std::string Line) {
    std::cout<<"[slot "<<SlotID_<<"] :"<<Line<<'\n';
}

class THAL
{
    using nHandle = int;
    nHandle HardwareHandle_;
    TLogger& Logger_;
public:
    THAL(nHandle HardwareHandle, TLogger& Logger);
    ~THAL();
};

THAL::THAL(nHandle HardwareHandle, TLogger& Logger):
HardwareHandle_(HardwareHandle),
Logger_(Logger)
{}

THAL::~THAL() {
    Logger_.Log("Closing device " + std::to_string(HardwareHandle_));
}

void runThread(States* state, int x) {
    // int slotId(std::hash<std::thread::id>(std::this_thread::get_id()));
    int slotId = std::hash<std::thread::id>{}(std::this_thread::get_id());
    TLogger logger(slotId, *state);
    THAL hw(1, logger);
}

int main() {
    States* state = new States;
    state->setData(5);
    std::thread t(runThread, state, 1);
    std::thread t2(runThread, state, 2);
    t.join();
    t2.join();
}

可能的 output:

[slot 18446744072947625951] :Closing device 2
[slot 18446744071970489560] :Closing device 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM