如果我在.cpp中实现类的create方法,我得到
错误LNK2019:未解析的外部符号“protected:__thiscall Singleton :: Singleton(void)”(?? 0Singleton @@ IAE @XZ)在函数“public:static void __cdecl Singleton :: create(void)”中引用(?创建@ @@辛格尔顿SAXXZ
但是,如果我在头文件中实现该方法,则编译时没有任何错误:S
头文件
#pragma once
#include <iostream>
class Singleton
{
public:
static Singleton * getInstance()
{
return s_instance;
}
static void create();
static void destroy();
void help();
protected:
static Singleton * s_instance;
Singleton();
};
源文件:
#include "Singleton.h"
Singleton * Singleton::s_instance = NULL;
void Singleton::create()
{
if (!s_instance)
{
s_instance = new Singleton;
}
}
void Singleton::destroy()
{
delete s_instance;
s_instance = NULL;
}
但是如果我在头部内实现create方法,它不会抛出任何错误
在其中实现create方法的头文件
#pragma once
#include <iostream>
class Singleton
{
public:
static Singleton * getInstance()
{
return s_instance;
}
static void create(){
if (!s_instance)
{
s_instance = new Singleton;
}
}
static void destroy();
protected:
static Singleton * s_instance;
Singleton();
};
答案 0 :(得分:3)
在cpp中,你的create函数试图通过使用new运算符初始化Singleton,但是你没有给它一个构造函数。尝试向Singleton()
提供实施。即:
protected:
static Singleton * s_instance;
Singleton() {}
};
答案 1 :(得分:0)
您已声明一个默认构造函数,并且您正在使用它(在new
表达式中),但您尚未实现它。
只需删除构造函数声明:
protected:
static Singleton * s_instance;
// Singleton(); -- don't have this. Remove it.
};
使用protected
特性,该类是为继承而设计的,那么如何确保派生类只能通过单例机制实例化?
嗯,你没有太多控制派生类,所以最简单只是为了记录每个派生类应该声明和定义一个非public
默认构造函数。
但是,基于必须由派生程度最高的类初始化虚拟基础这一事实,可以使用一种技巧来强制执行此操作。这可以用来强制客户端代码在底部添加最终的类派生。其中大多数派生类是模板实例化,它定义了非公共构造函数。
更实际的替代方案是将事情颠倒过来。
也就是说,不是将Singleton
类设计为派生(由受保护的东西发出信号),而是将其设计为继承自客户端代码类。这意味着使用模板。 Andrei Alexandrescu在他的经典着作“现代C ++设计”中讨论了一些使用这种思想的单身方法。