简体   繁体   中英

How to not implicitly delete default operators?

The code I'm working on spawns multiple threads with each thread doing the same set of well-defined tasks. Those well-defined tasks can be nicely separated into modules which is where I'm failing ATM.

I got a logger class which gets instantiated and initialized

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

The reason is that all loggers write into the same log, henceforth I need the SlotID to write to the log as well. It is immutable as long as that particular thread runs. The state also needs to be logged, but it is mutable. It is mutated by the thread function (which creates & initializes it's own logger).

I'm trying to create a HAL instance which runs in the same thread and accesses hardware. Those accesses need to be logged so I want to give the instance of the HAL running in the current thread a reference to this thread's logger

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;
}

The compiler says

'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)

If I read this right, the compiler does ALMOST the right thing by giving my class gets an =-operator, but kills it afterwards.

Save for switching to raw pointers, how can I get a reference to the thread-local logger into the thread-local HAL?

If I only had one thread, I'd declare everything as static singletons and call it a day but alas, this isn't a hobby project with optional boundary conditions.

As I see it, your current code has another problem apart from the one mentioned in the question. TLogger too can't have a default constructor since non-static reference members can't be initialized with default constructors. One way I see to get around this is moving Init() functionality to the constructors (which are supposed to initialize objects before usage) of the classes and using a member-initializer list as follows:

#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();
}

Possible output:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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