Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 避免使用qRegisterMetaType(指针与引用),关注常量_Qt - Fatal编程技术网

Qt 避免使用qRegisterMetaType(指针与引用),关注常量

Qt 避免使用qRegisterMetaType(指针与引用),关注常量,qt,Qt,发出信号: void dbConnected(const QSqlDatabase &db); 我从中学到了如何避免使用 qRegisterMetaType<QSqlDatabase>("QSqlDatabase"); 在吃角子老虎的那一边,我会用这样的东西: void onDBConnected(QSqlDatabase * const db); 我关心的是db的使用(正如在一开始我已经做了引用常量),所以我在这里把它设置为常量(在插槽端)。我也试着在信号方面做同样的

发出信号:

void dbConnected(const QSqlDatabase &db);
我从中学到了如何避免使用

qRegisterMetaType<QSqlDatabase>("QSqlDatabase");
在吃角子老虎的那一边,我会用这样的东西:

void onDBConnected(QSqlDatabase * const db);
我关心的是db的使用(正如在一开始我已经做了引用常量),所以我在这里把它设置为常量(在插槽端)。我也试着在信号方面做同样的事情

void dbConnected(QSqlDatabase*const db)

但是这样做,我就得到了运行时错误(在中提到)。所以我尝试了另一种形式,似乎可以做到这一点:

void dbConnected(QSqlDatabase *db) const;
我的方向对吗

我的方向对吗

也许吧。首先,确保您知道不能将数据库传递给另一个线程中的对象。这是你在另一个问题的代码中犯的主要错误之一。别再那样做了

如果通过引用传递对象,则该对象必须是可复制的。打开
QSqlDatabase
后,可以对其进行复制。所以你在这里也很好

但是您可能根本不需要传递数据库引用
QSqlDatabase
为每个连接指定一个名称。您可以传递数据库的连接名称,而不是通过值或指针传递数据库,并使用
QSqlDatabase::database
获取表示给定连接的数据库对象

例如:

class Opener : public QObject {
  Q_OBJECT
  QSqlDatabase m_db;
public:
  Q_SIGNAL void dbOpened(const QString &);
  void open() {
    m_db.addDatabase("FOO", "cats");
    ...
    if (m_db.open()) emit dbOpened(m_db.connectionName());
  }
};

class DbUser : public QObject {
  Q_OBJECT
  QSqlDatabase m_db;
public:
  Q_SLOT void onDbOpened(const QString & conn) {
    m_db = QSqlDatabase::database(conn);
  }
  ...
};

如您所见,
dbOpened
信号发出的不是一个数据库,而是一个数据库连接名称,然后希望使用该连接的各种对象可以按名称检索数据库对象(句柄)。

我已将引用设置为const no,您已将引用设置为const对象。不存在“常量引用”这类东西,因为引用总是常量——您不能重新放置它们。
const T&r
(参考const T)的逻辑等价物是
const T*const p
(指向const T的const指针)。你做的是一个指向非常量的常量指针;但是函数签名中的顶级常量不是函数签名的一部分(它们只是禁止您在函数体中修改
db
)。无论如何:您仍然需要声明元类型!好的,明白了。我是否可以得出这样的结论:一般来说,我更愿意传递引用并声明元类型?或者中提到的替代方法(不声明元类型并传递指针)也是可接受的?
class Opener : public QObject {
  Q_OBJECT
  QSqlDatabase m_db;
public:
  Q_SIGNAL void dbOpened(const QString &);
  void open() {
    m_db.addDatabase("FOO", "cats");
    ...
    if (m_db.open()) emit dbOpened(m_db.connectionName());
  }
};

class DbUser : public QObject {
  Q_OBJECT
  QSqlDatabase m_db;
public:
  Q_SLOT void onDbOpened(const QString & conn) {
    m_db = QSqlDatabase::database(conn);
  }
  ...
};