代码之家  ›  专栏  ›  技术社区  ›  Erik Johnson

将qmutex添加到类后“尝试引用已删除的函数”

  •  0
  • Erik Johnson  · 技术社区  · 7 年前

    我正在用qt5构建一个应用程序。我的程序构建和运行良好,但访问数据结构的两个线程之间存在冲突。我有一个canmessage对象的qlist,我想使用qmutex保护其中的一些数据。但是,一旦我将qmutex添加到类定义中,就会出现错误:

    QList.h: `error: C2280: 
    'CanMessage::CanMessage(const CanMessage &)': attempting to reference a deleted function`. 
    

    这是我的 canmessage.h 文件:

    #ifndef CANMESSAGE_H
    #define CANMESSAGE_H
    
    #include <QObject>
    #include <QMutex>
    #include "cansignal.h"
    
    class CanMessage
    {
    public:
        CanMessage();
        /* snip - public function prototypes */
    
    private:
        /* snip - private prototypes and data */
        QMutex m_messageMutex;
    };
    
    #endif // CANMESSAGE_H
    

    cansignal.h 以下内容:

    #ifndef CANSIGNAL_H
    #define CANSIGNAL_H
    
    #include <QObject>
    #include <QDebug>
    #include <QByteArray>
    
    class CanSignal
    {
    public:
        CanSignal();
    
        CanSignal(QString &signalName, quint8 &signalLength, quint8 &signalStartBit,
                       float &offset, float &factor, bool &isBigEndian, bool &isFloat, bool &isSigned)
        {
            this->m_name = signalName;
            this->m_length = signalLength;
            this->m_startBit = signalStartBit;
            this->m_offset = offset;
            this->m_factor = factor;
            this->m_isBigEndian = isBigEndian;
            this->m_isFloat = isFloat;
            this->m_isSigned = isSigned;
        }
    
        bool setName(QString &signalName);
        bool setBitLength(quint8 &length);
        bool setStartBit(quint8 &startBit);
        bool setOffset(float &offset);
        bool setFactor(float &factor);
        bool setEndianess(bool &isBigEndian);
        bool setIsFloat(bool &isFloat);
        bool setIsSigned(bool &isSigned);
        void setValid();
        void setInvalid();
        void setEngineeringData(float data);
    
        QString getName();
        quint8 getBitLength();
        quint8 getStartBit();
        float getOffset();
        float getFactor();
        float getData();
        bool isBigEndian();
        bool isFloat();
        bool isSigned();
        bool getSignalValidity();
    
    
    private:
        QString m_name;
        quint8 m_length;
        quint8 m_startBit;
        float m_offset;
        float m_factor;
        float m_data_float = 0;
        bool m_isBigEndian;
        bool m_isFloat;
        bool m_isSigned;
        // Set After everything in signal is filled
        bool m_isSignalValid = false;
    };
    
    #endif // CANSIGNAL_H
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   cbuchart    7 年前
    CanMessage::CanMessage(const CanMessage &)
    

    是复制构造函数,显然用于将项放入列表中。从那以后就没用了 QMutex 事实上

    CanMessage 所以它有一个动态互斥体(当然是在构造函数中创建的)。

    来源 目标对象中的互斥体。

    (a)


    下面的代码是一个显示问题的完整的简单代码段,如果您离开 QMutex m_mutex;

    #include <QList>
    #include <QMutex>
    
    #include <iostream>
    
    class Xyzzy {
    private:
        int m_xyzzy;
        //QMutex m_mutex;
    public:
        Xyzzy() : m_xyzzy(0) {};
        Xyzzy(int val) : m_xyzzy(val) {};
    };
    
    int main() {
        QList<Xyzzy> myList;
        Xyzzy plugh;
        myList.push_back(plugh);
        return 0;
    }
    

    一旦你

     error: use of deleted function 'Xyzzy::Xyzzy(const Xyzzy&)'
    

    在解决问题方面,您可以执行以下操作:

    #include <QList>
    #include <QMutex>
    
    #include <iostream>
    
    class Xyzzy {
    private:
        int m_xyzzy;
        QMutex *m_mutex; // Now a pointer
    public:
        Xyzzy() : m_xyzzy(0) {
            m_mutex = new QMutex(); // Need to create in constructor.
            std::cout << "constructor " << m_mutex << '\n';
        };
        ~Xyzzy() {
            std::cout << "destructor " << m_mutex << '\n';
            delete m_mutex; // Need to delete in destructor.
        }
        Xyzzy(const Xyzzy &old) {
            old.m_mutex->lock();
            m_mutex = new QMutex(); // Need to make new one here.
            std::cout << "copy constructor from " << old.m_mutex
                      << " to " << m_mutex << '\n';
            old.m_mutex->unlock();
        }
    };
    
    int main() {
        QList<Xyzzy> myList;
        Xyzzy plugh;
        myList.push_back(plugh);
        return 0;
    }
    

    constructor 0x21c9e50
    copy constructor from 0x21c9e50 to 0x21c9ec0
    destructor 0x21c9e50
    destructor 0x21c9ec0
    

    new/delete Xyzzy &operator=(const Xyzzy &old)