实际开发中,两个不同的类对象有时要完成数据交互,需要能够获取到对方,如何获取?
- 通过函数参数进行传递。
- 使用起来有些麻烦,每次都要传参,或者使用者都要维护一个类成员变量。当有很多类都使用时,会更显得繁琐。
- 单例模式
- 并非所有的类都按照单例进行实现。
此处的思路是引入一个中间对象,单例的容器,用于存取变量。
这样,可以在初始化时将需要用的对象,特别是那些几乎只会有一个实例的类,会方便许多。
#pragma once
#include <QDebug>
#include <QString>
#include <map>
#include <memory>
class PointerInstancePool {
public:
static PointerInstancePool &instance()
{
static PointerInstancePool instance;
return instance;
}
template <typename T>
void setDefaultInstance(T *instance);
template <typename T>
T *getDefaultInstance();
template <typename T>
bool setInstance(const QString &key, T *instance, bool overwrite = false);
template <typename T>
T *getInstance(const QString &key);
private:
template <typename T>
QString generateDefaultId();
PointerInstancePool() = default;
PointerInstancePool(const PointerInstancePool &) = delete;
PointerInstancePool &operator= (const PointerInstancePool &) = delete;
std::map<QString, void *> m_pool;
};
template <typename T>
void
PointerInstancePool::setDefaultInstance(T *instance)
{
QString id = generateDefaultId<T>();
bool ret = setInstance(id, instance, true);
assert(ret);
}
template <typename T>
T *
PointerInstancePool::getDefaultInstance()
{
QString id = generateDefaultId<T>();
return getInstance<T>(id);
}
template <typename T>
bool
PointerInstancePool::setInstance(const QString &key, T *instance, bool overwrite)
{
if (m_pool.find(key) == m_pool.end()) {
m_pool[key] = instance;
} else {
if (overwrite) {
m_pool[key] = instance;
} else {
qWarning() << "Instance with key " << key << " already exists";
return false;
}
}
return true;
}
template <typename T>
T *
PointerInstancePool::getInstance(const QString &key)
{
auto it = m_pool.find(key);
if (it == m_pool.end()) {
qWarning() << "Instance with key " << key << " not found";
return nullptr;
}
void *ptr = it->second;
return reinterpret_cast<T *>(ptr);
}
template <typename T>
QString
PointerInstancePool::generateDefaultId()
{
return QString(typeid(T).name());
}