std::thread jako element klasy

0

Witam.
Dlaczego poniższy kod przy próbie kompilacji zwraca błędy i w jaki sposób można to naprawić?
main.cpp

#include "B.h"

B b;

int main()
{
	std::thread mainThread;

	mainThread = std::thread(&B::Logic, b);
	mainThread.detach();

	return 0;
}

B.h

#pragma once
#include "A.h"

class B
{

	A a;

public:

	void Logic();

};

B.cpp

#include "B.h"

void B::Logic()
{
	a.Start();

	while (true)
	{

	}
}

A.h

#pragma once
#include <thread>

class A
{

	std::thread mainThread;

	void Logic();

public:

	void Start();
};

A.cpp

#include "A.h"

void A::Logic()
{
	while (true)
	{

	}
}


void A::Start()
{
	mainThread = std::thread(&A::Logic, this);
	mainThread.detach();
}

Error C2280 'B::B(const B &)': attempting to reference a deleted function ...\microsoft visual studio 14.0\vc\include\tuple 75

Po usunięciu std::thread mainThread z klasy A problem nie występuje, jednak zależy mi na stworzeniu wątku wewnątrz klasy, który będzie uruchamiał jej funkcję.

Wątek z main.cpp służy do uruchomiania głównej funkcji programu odpowiedzialnej za logikę, dzięki czemu główne okno programu nie jest zawieszone (WinApi).
Wątek z klasy A służy do przesyłu logów programu na serwer, mógłbym stworzyć go jako globalny obiekt w pliku main.cpp, a następnie przesłać do A, jednak to rozwiązanie nie wydaje mi się zbyt eleganckie.

4

Chyba przez to, że nie podajesz wskaźnika tylko próbujesz podać cały obiekt b
zmień to

mainThread = std::thread(&B::Logic, b);

na

mainThread = std::thread(&B::Logic, &b);
5

Klasa thread nie ma konstruktora kopiującego, ma jedynie konstruktor przenoszący, bo kopiowanie wątku jest bez sensu.

error: use of deleted function 'std::thread::thread(const std::thread&)'

Z tego powodu kompilator usunął konstruktor kopiujący klasy A (konstruktor kopiujący kopiowałby mainThread).

error: use of deleted function 'A::A(const A&)'
note: 'A::A(const A&)' is implicitly deleted because the default definition would be ill-formed

Z tego samego powodu B nie ma konstruktora kopiującego.

error: use of deleted function 'B::B(const B&)'
note: 'B::B(const B&)' is implicitly deleted because the default definition would be ill-formed

A próbujesz kopiować obiekt klasy B gdy wywołujesz konstruktor thread z obiektem będącym l-value.

required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (B::*)(); _Args = {B&}]'

Rozwiązanie: przekazać r-value do konstruktora thread

mainThread = std::thread(&B::Logic, move(b));

mainThread = std::thread(&B::Logic, B());

4

Przy okazji: jeśli klasa zawiera std::thread to powinien być on inicjalizowany po wszystkich elementach klasy (czyli powinien być na samym dole definicji klasy), z których ten wątek będzie korzystał, inaczej ryzykujesz UB w postaci dostępu do niezainicjalizowanych zmiennych.

1 użytkowników online, w tym zalogowanych: 0, gości: 1