Qt 中 QObjects 的引用赋值是如何完成的?

Nul*_*lik 2 c++ qt qt5

在 Qt 中,当尝试分配引用时出现use of deleted function错误:

/home/niko/QT_snippets/QML1/users.cpp:16: error: use of deleted function 'User::User(const User&)'
     User user=users_map.value("email@domain.com");
                                                 ^
         ^
/home/niko/QT_snippets/QML1/users.h:7: In file included from ../QML1/users.h:7:0,
/home/niko/QT_snippets/QML1/users.cpp:1: from ../QML1/users.cpp:1:
/home/niko/QT_snippets/QML1/user.h:6: 'User::User(const User&)' is implicitly deleted because the default definition would be ill-formed:
 class User : public QObject
       ^
/opt/Qt/5.7/gcc_64/include/QtCore/QObject:1: In file included from /opt/Qt/5.7/gcc_64/include/QtCore/QObject:1:0,
/home/niko/QT_snippets/QML1/users.h:4: from ../QML1/users.h:4,
/home/niko/QT_snippets/QML1/users.cpp:1: from ../QML1/users.cpp:1:
Run Code Online (Sandbox Code Playgroud)

在 C 中,我总是使用指针,从来没有遇到过任何问题,但正如我在 C++ 中看到的那样,每个人都使用引用。

我应该如何在 Qt 中通过引用分配对象?例如,在这一行中,我应该如何使对象成为对对象user中值的引用?users_map

User user=users_map.value("email@domain.com");
Run Code Online (Sandbox Code Playgroud)

或者也许是以下内容?

User user=&users_map.value("email@domain.com");
Run Code Online (Sandbox Code Playgroud)

因为...上面的代码无法编译。我需要在Users类的方法内部使用它来访问变量中的数据users_map

该类Users声明为:

class Users : public QAbstractItemModel
{
    Q_OBJECT
    enum UserRoles {
        EmailRole = Qt::UserRole + 1,
        NameRole,
        PasswordRole
    };
private:
    QMap<QString,User>         users_map;
public:
    explicit Users(QAbstractItemModel *parent = 0);
    Q_INVOKABLE QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const;
    Q_INVOKABLE QModelIndex parent(const QModelIndex &child) const;
    Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const;
    Q_INVOKABLE int columnCount(const QModelIndex &parent = QModelIndex()) const;
    Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    QHash<int, QByteArray> roleNames() const;
signals:

public slots:
};
Run Code Online (Sandbox Code Playgroud)

该类User声明如下:

class User : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString email READ get_email WRITE set_email NOTIFY emailChanged);
    Q_PROPERTY(QString name READ get_name WRITE set_name NOTIFY nameChanged);
    Q_PROPERTY(QString password READ get_password WRITE set_password NOTIFY passwordChanged);
private:
    QString             email;
    QString             name;
    QString             password;
public:
    explicit User(QObject *parent = 0);
    QString get_email();
    void set_email(QString data);
    QString get_name();
    void set_name(QString data);
    QString get_password();
    void set_password(QString data);

signals:
    void emailChanged();
    void nameChanged();
    void passwordChanged();

public slots:
};
Run Code Online (Sandbox Code Playgroud)

was*_*ful 5

正如我在 C++ 中看到的,每个人都使用引用。

你不应该相信你所看到的:)


QObject有一个已删除的复制构造函数,因此事实上您的派生类也User有一个已删除的复制构造函数并且无法复制。这就是这个错误的含义:

use of deleted function 'User::User(const User&)'
Run Code Online (Sandbox Code Playgroud)

在下面一行中:

User user=&users_map.value("email@domain.com");
Run Code Online (Sandbox Code Playgroud)

获取&的地址users_map.value("email@domain.com"),因此您基本上是在创建一个指向User*copy by 返回的元素类型的(悬空)指针QMap::value

您可以像这样更改代码以获得参考:

User& user=users_map["email@domain.com"];
Run Code Online (Sandbox Code Playgroud)

请注意,没有QMap::value返回引用的实现,因此您必须在此处使用QMap::operator[](您可能需要检查是否"email@domain.com"确实是映射中包含的键;否则它将被静默添加)。

但是请注意,QObject(和派生类)被设计为与指针一起使用,因此您的声明:

QMap<QString, User> users_map;
Run Code Online (Sandbox Code Playgroud)

从 Qt 的角度来看,这看起来是一个糟糕的设计,并且您可能会遇到更多此类错误。


顺便说一句,正确的拼写是 Qt,而不是代表 QuickTime 的 QT;)