【问题标题】:How do you append an object to QList?如何将对象附加到 QList?
【发布时间】:2014-10-05 23:08:47
【问题描述】:

我正在尝试使用 QList 创建一个对象列表,但是当我尝试添加到列表时出现错误。如果我使用 QString 作为对象,它可以工作,但如果我使用 TestClass 则不行。

更新了可以工作的 main.cpp。这是正确的做事方式吗?

#include <QCoreApplication>
#include <QDebug>

#include "testclass.h"

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

    QList<TestClass*> test_list;

    TestClass* test_1 = new TestClass;
    test_1->test_varialbe = 1;
    test_list.append(test_1);

    TestClass* test_2 = new TestClass;
    test_2->test_varialbe = 2;
    test_list.append(test_2);

    foreach(TestClass* t, test_list) {
        qWarning() << t->test_varialbe;
    }

    return a.exec();
}

main.cpp

#include <QCoreApplication>

#include "testclass.h"

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

    QList<TestClass> test_list;
    TestClass test;
    test_list.append(test);

    return a.exec();
}

testclass.h

#ifndef TESTCLASS_H
#define TESTCLASS_H

#include <QObject>

class TestClass : public QObject
{
    Q_OBJECT
public:
    explicit TestClass(QObject *parent = 0);
    int test_varialbe;

signals:

public slots:

};

#endif // TESTCLASS_H

testclass.cpp

#include "testclass.h"

TestClass::TestClass(QObject *parent) :
    QObject(parent)
{
}

错误

In file included from ../poo/main.cpp:3:
../poo/testclass.h:6:7: error: base class 'QObject' has private copy constructor
class TestClass : public QObject
      ^
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qlist.h:691:9: note: in instantiation of member function 'QList<TestClass>::node_copy' requested here
        node_copy(reinterpret_cast<Node *>(p.begin()),
        ^
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qlist.h:520:19: note: in instantiation of member function 'QList<TestClass>::detach_helper_grow' requested here
        Node *n = detach_helper_grow(INT_MAX, 1);
                  ^
../poo/main.cpp:11:15: note: in instantiation of member function 'QList<TestClass>::append' requested here
    test_list.append(test);
              ^
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qobject.h:465:20: note: declared private here
    Q_DISABLE_COPY(QObject)
                   ^
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qglobal.h:1000:5: note: expanded from macro 'Q_DISABLE_COPY'
    Class(const Class &) Q_DECL_EQ_DELETE;\
    ^
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qlist.h:400:34: note: implicit copy constructor for 'TestClass' first required here
                current->v = new T(*reinterpret_cast<T*>(src->v));
                                 ^
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qlist.h:413:31: error: no matching constructor for initialization of 'TestClass'
                new (current) T(*reinterpret_cast<T*>(src));
                              ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
../poo/testclass.h:10:14: note: candidate constructor not viable: no known conversion from 'TestClass' to 'QObject *' for 1st argument; remove *
    explicit TestClass(QObject *parent = 0);
             ^
In file included from ../poo/main.cpp:1:
In file included from ../Qt/5.3/clang_64/lib/QtCore.framework/Versions/5/Headers/QCoreApplication:1:
In file included from ../Qt/5.3/clang_64/lib/QtCore.framework/Versions/5/Headers/qcoreapplication.h:48:
In file included from /Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qobject.h:51:
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qlist.h:373:69: error: no matching constructor for initialization of 'TestClass'
    if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
                                                                    ^ ~
/Users/waspinator/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qlist.h:522:13: note: in instantiation of member function 'QList<TestClass>::node_construct' requested here
            node_construct(n, t);
            ^
../poo/main.cpp:11:15: note: in instantiation of member function 'QList<TestClass>::append' requested here
    test_list.append(test);
              ^
../poo/testclass.h:10:14: note: candidate constructor not viable: no known conversion from 'const TestClass' to 'QObject *' for 1st argument
    explicit TestClass(QObject *parent = 0);
             ^
3 errors generated.
make: *** [main.o] Error 1
14:37:52: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project poo (kit: Desktop Qt 5.3.0 clang 64bit)
When executing step 'Make'

【问题讨论】:

    标签: c++ qt5 qlist


    【解决方案1】:

    来自QList 的文档:

    QList 的值类型必须是可分配的数据类型。这涵盖了大部分 常用的数据类型,但编译器不会让你,因为 例如,将 QWidget 存储为值;相反,存储一个 QWidget *.

    另请参阅 Qt 的 Container Classes 上的文档。

    总而言之,如果您希望将指针与 QList 一起使用,则必须使用指向 QObject 的指针:

    QList<TestClass*> test_list;
    

    请注意,这意味着如果您的代码仍在使用QList,您有责任确保QObject 未被删除。


    更新:同样,您负责管理插入到列表中的QObject 的生命周期。有几种方法可以做到这一点。您可以在堆上实例化 TestClass,但您应该确保在应用程序退出时删除该对象。一种方法是给 TestClass 一个父对象:

    QCoreApplication a(argc, argv);
    
    QList<TestClass*> test_list;
    
    TestClass* test_1 = new TestClass(&a);
    test_list.append(test_1);
    

    您也可以完全避免在堆上创建TestClass,尽管它会在创建它的函数超出范围时自动销毁:

    QList<TestClass*> test_list;
    TestClass test_1;
    test_list.append(&test_1);
    

    我强烈建议研究 C++ 中的内存管理,以及堆栈和堆的作用(以及何时使用它们)。范围太广,无法在此介绍。

    【讨论】:

    • 那么我可以将 TestClass 测试更改为 TestClass* test = new TestClass 吗?否则似乎无法编译。
    【解决方案2】:

    您收到此错误是因为 QList 无法访问您的 TestClass 的默认构造函数。您可以定义一个而不是使用指针。在大多数情况下,您还需要复制构造器。

    public:
        TestClass();
        TestClass(const TestClass &oth);
    

    如果您愿意,您也可以对其他用户隐藏它们。

    private:
        TestClass();
        TestClass(const TestClass &oth);
    
    ...
    
    private:
        template<class T> friend class QList;
    

    【讨论】:

      猜你喜欢
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      • 2013-07-04
      • 2019-04-23
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多