是否可以使用 QObject 继承创建单例类?添加 QObject 继承后出现编译错误。也许问题在于静态单例创建(应该是动态的)?这是我的方法
标题
#ifndef BLUETOOTHMANAGER_H
#define BLUETOOTHMANAGER_H
#include <QObject>
class BluetoothManager : public QObject
{
Q_OBJECT
public:
virtual ~BluetoothManager() {}
/// Static getter
static BluetoothManager & GetInstance()
{
return instance;
}
private:
/// static Bluetooth manager instance
static BluetoothManager instance;
explicit BluetoothManager(QObject * parent);
};
#endif // BLUETOOTHMANAGER_H
Run Code Online (Sandbox Code Playgroud)
和cpp文件
#include "BluetoothManager.h"
/// singleton creation
BluetoothManager BluetoothManager::instance = BluetoothManager(static_cast<QObject*>(nullptr));
BluetoothManager::BluetoothManager(QObject * parent)
: QObject(parent)
{
}
Run Code Online (Sandbox Code Playgroud)
在编译期间我有一个错误
../QtHealthApp/network/bluetooth/BluetoothManager.cpp:4:94: error: use of deleted function ‘BluetoothManager::BluetoothManager(const BluetoothManager&)’ BluetoothManager BluetoothManager::instance = BluetoothManager(static_cast<QObject*>(nullptr));
^ In file included from /opt/Qt5.12.LTS/5.12.6/gcc_64/include/QtCore/qnamespace.h:43:0,
from /opt/Qt5.12.LTS/5.12.6/gcc_64/include/QtCore/qobjectdefs.h:48,
from /opt/Qt5.12.LTS/5.12.6/gcc_64/include/QtCore/qobject.h:46,
from /opt/Qt5.12.LTS/5.12.6/gcc_64/include/QtCore/QObject:1,
from ../QtHealthApp/network/bluetooth/BluetoothManager.h:4,
from ../QtHealthApp/network/bluetooth/BluetoothManager.cpp:1: ../QtHealthApp/network/bluetooth/BluetoothManager.h:33:20: note: declared here
Q_DISABLE_COPY(BluetoothManager)
^ /opt/Qt5.12.LTS/5.12.6/gcc_64/include/QtCore/qglobal.h:372:5: note: in definition of macro ‘Q_DISABLE_COPY’
Class(const Class &) Q_DECL_EQ_DELETE;\
^
Run Code Online (Sandbox Code Playgroud)
首先,您应该将构造函数设为私有,与单例模式意图一致,以确保一个类只有一个实例。如果您让每个人都使用公共构造函数构建自己的实例,则不能将您的类称为单例。
然后,在您的实现中,您正在使用复制构造初始化您的实例:
BluetoothManager BluetoothManager::instance = BluetoothManager(static_cast<QObject*>(nullptr));
Run Code Online (Sandbox Code Playgroud)
你不能这样做,因为QObject
已经删除了复制构造函数(这很好,毕竟在制作单例时)。
只需给构造函数参数一个默认值:
explicit BluetoothManager(QObject * parent = nullptr);
Run Code Online (Sandbox Code Playgroud)
这样您的实例定义就可以是:
BluetoothManager BluetoothManager::instance;
Run Code Online (Sandbox Code Playgroud)
这个问题应该消失了。
另外,我建议你在 C++ 中使用一个非常流行的单例变体,众所周知,它可以避免静态初始化顺序 'fiasco':将静态实例从类作用域移动到GetInstance
函数作用域:
class BluetoothManager : public QObject
{
Q_OBJECT
public:
virtual ~BluetoothManager() {}
/// Static getter
static BluetoothManager & GetInstance()
{
static BluetoothManager instance;
return instance;
}
private:
explicit BluetoothManager(QObject * parent = nullptr){}
};
Run Code Online (Sandbox Code Playgroud)