【发布时间】:2022-08-14 06:40:54
【问题描述】:
我收到attempting to reference a deleted function 错误,我觉得这是因为类之间的相互依赖。
Location.h
#ifndef A_LOCATION_H
#define A_LOCATION_H
struct location {
double lat;
double lon;
double alt;
};
#endif //A_LOCATION_H
P.h
#ifndef A_P_H
#define A_P_H
#include <vector>
#include <mutex>
#include <memory>
#include \"Location.h\"
class C;
class P {
std::vector<std::shared_ptr<C>> C_List;
struct location loc {};
public:
P() = default;
~P() = default;
std::mutex mut;
void add_child(const std::string& th_name);
void del();
void set_data(double lat, double lon, double alt);
struct location get_data();
};
#endif //A_P_H
P.cpp
#include <iostream>
#include \"C.h\"
#include \"P.h\"
void P::add_child(const std::string& th_name) {
std::lock_guard<std::mutex> lg(mut);
auto& ref = C_List.emplace_back(std::make_shared<C>());
ref->set_name(th_name);
ref->set_P(this);
ref->start();
}
void P::del() {
std::lock_guard<std::mutex> lg(mut);
for (auto& c : C_List)
c->terminate = true;
for (auto& c : C_List)
c->wait();
C_List.clear();
}
struct location P::get_data() {
std::lock_guard<std::mutex> lg(mut);
return loc;
}
void P::set_data(double lat, double lon, double alt) {
std::lock_guard<std::mutex> lg(mut);
loc.lat = lat;
loc.lon = lon;
loc.alt = alt;
}
C.h
#ifndef A_C_H
#define A_C_H
#include <string>
#include <thread>
#include <chrono>
#include <atomic>
class P;
class C {
P *p {};
std::string name {};
std::thread th {};
struct location loc {};
void run();
public:
C() = default;
~C() = default;
void set_P(P* p);
void set_name(const std::string& name);
void start();
void wait();
std::atomic<bool> terminate {false};
};
#endif //A_C_H
C.cpp
#include <iostream>
#include \"P.h\"
#include \"C.h\"
void C::run() {
while (!terminate) {
std::cout << name << std::endl;
{
auto loc = p->get_data();
// perform calculation based on P\'s object location, and it\'s current location
}
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
}
}
void C::set_P(P* p) {
this->p = p;
}
void C::set_name(const std::string& name) {
this->name = name;
}
void C::start() {
th = std::thread(&C::run, this);
}
void C::wait() {
th.join();
}
Main.cpp
#include <iostream>
#include \"P.h\"
int main() {
P p = P();
p.add_child(\"C1\");
p.add_child(\"C2\");
p.add_child(\"C3\");
char input;
std::cin >> input;
p.del();
}
当P\'s对象的del函数被调用时,也存在一种死锁。我没有得到如何解决这个问题?
这是我得到的错误的简短描述
C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.26.28801\\include\\xmemory(671): error C2280: \'C::C(const C &)\': attempting to reference a deleted function
C:\\Users\\HARSHA\\Desktop\\LC\\2022\\A\\C.h(33): note: compiler has generated \'C::C\' here
C:\\Users\\HARSHA\\Desktop\\LC\\2022\\A\\C.h(33): note: \'C::C(const C &)\': function was implicitly deleted because a data member invokes a deleted or inaccessible function \'std::thread::thread(const std::thread &)\'
C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.26.28801\\include\\thread(93): note: \'std::thread::thread(const std::thread &)\': function was explicitly deleted
-
仅供参考,
P p = P();是多余的。P p;。这不是 Java 或 C#。 -
由于
std::thread成员,C是不可复制的,因此您需要小心避免对C_List进行任何需要复制的操作 -
我对标题的规则是:如果你不需要包含它,就不要包含它。在您的情况下,
P.h和C.h相互包含,导致包含顺序可能出现问题。C.h中的#include \"P.h\"应该被删除,因为P的前向声明就足够了。将此包含添加到C.cpp中。 -
您没有在该 Cs 容器中使用随机访问。您可以只使用
std::list<C>。 -
还要注意
std::atomic<bool> terminate {};不会初始化原子的值;您需要为此使用std::atomic_init或简单地提供初始值std::atomic<bool> terminate { false };原子的存在使C既不可移动也不可复制,这是用作std::vector的模板参数所必需的。你可以用std::unique_ptr<C>替换模板参数来解决这个问题。这也使得在P.h中使用C的前向声明就足够了,只要你在P中实现P的构造函数/析构函数@(你可以= default他们)
标签: c++