【问题标题】:attempting to reference a deleted function because of inter dependency between classes由于类之间的相互依赖关系,试图引用已删除的函数
【发布时间】: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.hC.h 相互包含,导致包含顺序可能出现问题。 C.h 中的 #include \"P.h\" 应该被删除,因为 P 的前向声明就足够了。将此包含添加到 C.cpp 中。
  • 您没有在该 Cs 容器中使用随机访问。您可以只使用std::list&lt;C&gt;
  • 还要注意std::atomic&lt;bool&gt; terminate {};不会初始化原子的值;您需要为此使用std::atomic_init 或简单地提供初始值std::atomic&lt;bool&gt; terminate { false }; 原子的存在使C 既不可移动也不可复制,这是用作std::vector 的模板参数所必需的。你可以用std::unique_ptr&lt;C&gt; 替换模板参数来解决这个问题。这也使得在P.h 中使用C 的前向声明就足够了,只要你在P 中实现P 的构造函数/析构函数@(你可以= default他们)

标签: c++


【解决方案1】:

std::thread、std::atomic、std::mutex 类型不可复制,因此编译器无法生成默认的复制构造函数和复制分配。

您必须为 C 和 P 类编写自己的复制构造函数。

P(P const& arg){ ... do stuff ... }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2018-08-14
    相关资源
    最近更新 更多