看完之后这个答案 https://stackoverflow.com/a/4173298/7151494我尝试过实现一些简单的 CRTP 用法。我想我会尝试实现 Singleton(是的,我知道 - 这只是为了练习和研究)模式,因为链接的答案kind of已经做到了...除了它无法编译这一事实。
引用的代码如下:
template <class ActualClass>
class Singleton
{
public:
static ActualClass& GetInstance()
{
if(p == nullptr)
p = new ActualClass;
return *p;
}
protected:
static ActualClass* p;
private:
Singleton(){}
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
};
template <class T>
T* Singleton<T>::p = nullptr;
class A: public Singleton<A>
{
//Rest of functionality for class A
};
然后我将其“现代化”为:
template <class T>
class Singleton {
public:
Singleton() = delete;
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator = (const Singleton&) = delete;
Singleton& operator = (Singleton&&) = delete;
static T& get_instance() {
if(!instance)
instance = new T;
return *instance;
}
protected:
static inline T* instance = nullptr;
};
class A: public Singleton<A> {
//Rest of functionality for class A
};
然后我尝试创建对该实例的引用:
auto& x = A::get_instance();
显然没有编译。
值得一提的是,我收到了非常相似的错误消息,特别是:
注意:“A::A()”被隐式删除,因为默认定义格式不正确:class A : public Singleton<A>
.
显然,第二段代码cannot编译,因为我们删除了默认构造函数并尝试将其与new T
in the get_instance
method.
令我惊讶的是,第一个代码片段也无法编译,并带有类似的错误消息。链接的答案有错误吗?我将如何实施单例的通用基类/接口使用CRTP?
这是“现代化”片段的修改:
template <class T>
class Singleton {
public:
Singleton& operator = (const Singleton&) = delete;
Singleton& operator = (Singleton&&) = delete;
static T& get_instance() {
if(!instance)
instance = new T_Instance;
return *instance;
}
protected:
Singleton() {}
private:
struct T_Instance : public T {
T_Instance() : T() {}
};
static inline T* instance = nullptr;
};
class A : public Singleton<A> {
protected:
A() {}
};
int main()
{
auto& x = A::get_instance();
}
代码片段的更改摘要:
-
protected
单例中的默认构造函数
-
private
嵌套结构来访问派生类的受保护构造函数
-
protected
派生类中的构造函数以防止实例化
另外,无需delete
通过向 Singleton 类添加默认 ctor 实现来隐式删除的构造函数。
不那么小理查德·霍奇斯 https://stackoverflow.com/users/2015579/richard-hodges' 示例,但是静态instance
member 可以轻松添加用于自动化单元测试的 delete_instance() 方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)