【问题标题】:Boost signals2 giving noncopyable errors增强信号2 给出不可复制的错误
【发布时间】:2015-12-15 21:53:38
【问题描述】:

我目前正在开发一个 C++ 应用程序,我需要在其中创建一个将升压信号发送到另一个类的模块。我正在使用 Document-View 示例作为我的应用程序 (http://www.boost.org/doc/libs/1_55_0/doc/html/signals2/tutorial.html#signals2.tutorial.document-view) 的基础,但我不断收到错误消息:

Error   1   error C2280: boost::noncopyable_::noncopyable::noncopyable(const   boost::noncopyable_::noncopyable &)' : attempting to reference a deleted function

这让我完全被难住了 - 错误实际发生在哪里?

构建日志如下:

1>------ Build started: Project: 32BitTrial, Configuration: Debug Win32 ------
1>  InboundLogicAdaptor.cpp
1>  main.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xlocmon(232): error C2280: 'boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable &)' : attempting to reference a deleted function
1>          C:\boost_1_58_0\boost/core/noncopyable.hpp(34) : see declaration of 'boost::noncopyable_::noncopyable::noncopyable'
1>          This diagnostic occurred in the compiler generated function 'boost::signals2::signal_base::signal_base(const boost::signals2::signal_base &)'
1>  OutboundLogicAdaptor.cpp
1>  TrialLogic.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我的主要功能相当简单 - 我构建了一个 GUI、一个用于与 GUI 通信的模型 (TrialModel)、一个每 500 毫秒计数 +1 的简单逻辑和一个出站逻辑适配器,可通过来自逻辑。

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    TrialModel m;

    Trial w(0, &m);
    w.show();


    TrialLogic logic;

    OutboundLogicAdaptor adaptor(&m, logic);

    boost::thread t(logic);

    a.exec();

    t.join();

    return 1;

}

逻辑类定义了一个信号,它有一个参数(整数)和一个用作线程的 operator()。

TrialLogic.h:

#pragma once

#include <boost\thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost\signals2.hpp>



class TrialLogic
{
public:
    typedef boost::signals2::signal<void(int x)> signal_t;

    void operator()();
    TrialLogic();
    ~TrialLogic();

    boost::signals2::connection connect(const signal_t::slot_type &subscriber);

    void doubleIncrementSlot();

private:

    void emitSignal();

    signal_t signal;

    int testNum;

};

和代码本身:

#include "TrialLogic.h"

TrialLogic::TrialLogic()
{   
    testNum = 0;
}


TrialLogic::~TrialLogic()
{
}

boost::signals2::connection TrialLogic::connect(const signal_t::slot_type &subscriber){
    return signal.connect(subscriber);
}

void TrialLogic::operator()(){
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    testNum++;
    emitSignal();

}

void TrialLogic::emitSignal(){
    signal_t(testNum);
}

最后是接收信号的适配器——

#include "OutboundLogicAdaptor.h"


OutboundLogicAdaptor::OutboundLogicAdaptor(TrialModel *modelHook, TrialLogic &logicHook) : logic(logicHook)
{
    this->hook = modelHook;

    signalConnection = logic.connect(boost::bind(&OutboundLogicAdaptor::transmitAngle, this, _1));
}



OutboundLogicAdaptor::~OutboundLogicAdaptor()
{
    signalConnection.disconnect();
}

void OutboundLogicAdaptor::transmitAngle(int angle){
    hook->postAngle(angle);
}

从我的第一次检查中,我找不到任何我做错的地方,但显然我的代码存在严重错误。我很确定问题也不在于 GUI 方面,因为我实际上并没有在那里使用任何增强功能,并且在我尝试将系统绑定在一起之前它运行良好。

有什么建议吗?

【问题讨论】:

    标签: c++ multithreading boost signals boost-signals2


    【解决方案1】:

    失败的原因如下:

    你的TrialLogic 类中有一个boost.signal 类型的成员,并且这个类型是不可复制的(它继承自signal_base,它继承自nocopyable)。这使得类TrialLogic 本身不可复制。然而你却试图在这里复制它:

    TrialLogic logic;
    boost::thread t(logic);
    

    Boost.thread 按值接受参数,因此您正在尝试复制不可复制的内容,编译器会感到不安。

    至于解决方案,最简单的方法似乎是:不要在 TrialLogic 上定义 operator(),而是定义一个函数,而不是传递该函数以及对逻辑类的指针或引用。类似的东西:

    class TrialLogic
    {
    ...
    void launch() {
        boost::this_thread::sleep(boost::posix_time::milliseconds(500));
        testNum++;
        emitSignal();
    }
    };
    ...
    // in main
    boost::thread(&TrialLogic::launch, &logic);
    

    最后但并非最不重要的一点是,我不建议使用 boost::thread。 C++11 线程支持完全可操作,而 boost::thread 并没有真正增加任何好处。

    【讨论】:

    • 哇 - 这解释了很多!但是,如果我不能复制它,有什么方法可以运行线程而不更新它?
    • @RainerKeerdo,我确实提供了一个建议。
    • 对不起,我在写评论的时候一定已经发布了!但是,是的,我会尝试使用 std::thread - 我在以前的项目中总是使用 boost 线程。
    • @RainerKeerdo,std::thread 与 boost::thread 更多的是侧面 cmets。真正的问题在于复制构造函数,对于 std:: 和 boost:: 来说是一样的。
    猜你喜欢
    • 2021-06-18
    • 2012-09-12
    • 2016-11-14
    • 1970-01-01
    • 2013-07-28
    • 2017-11-28
    • 1970-01-01
    • 2011-11-21
    • 2017-09-26
    相关资源
    最近更新 更多