我从我在网上找到的教程中调整了我的Singleton类。我的标题看起来像:
class Logger{
public:
static Logger *instance();
~Logger();
private:
Logger();
static Logger *instance_;
};
并且cpp文件是:
Logger* Logger::instance_=nullptr; //Confused about this
Logger *Logger::instance(){
if (instance_==nullptr){
instance_=new Logger();
}
return instance_;
}
Logger::Logger(){}
几个问题:
1)在我的cpp的第一行,如果我只写" Logger :: instance_ = nullptr;"然后我收到一个错误。由于它已经在标题中声明了,为什么我需要提一下instance_又是一个指针?
2)为什么我不能在头文件本身中初始化instance_为"静态Logger * instance_ = nullptr;"?这样做会给我以下错误:
错误:静态数据的类内初始化需要'constexpr' 成员'非整数类型的记录器*记录器:: instance_'[-fpermissive] static Logger * instance_ = nullptr; ^
谢谢!
答案 0 :(得分:2)
问题1)在我的cpp的第一行,如果我只写
Logger::instance_=nullptr;
,那么我会收到错误。由于它已经在标题中声明,为什么我需要提一下instance_又是一个指针?
来自C ++草案标准N3337:
9.4.2静态数据成员
命名空间范围内的类的5
static
个数据成员具有外部链接(3.5)。
声明
是有意义的extern int a;
<。>在.h文件中并定义
int a = 10;
在.cpp文件中。您必须在a
定义时指定static
的类型。
问题2)为什么我不能将头文件本身中的instance_初始化为“static Logger * instance_ = nullptr;”?
来自C ++ Draft Standard N3337(强调我的):
9.4.2静态数据成员
2
通过其类名限定void
数据成员在其类定义中的声明不是定义,除了cv-qualifiedstatic
之外,可能是不完整的类型。static
数据成员的定义应出现在包含成员类定义的命名空间范围内。在命名空间范围的定义中,namespace detail { class Foo { static int var; }; }
数据成员的名称应为使用:: operator。
更新,以回应OP的评论
说你有:
Foo::var
必须在namespace
的封闭Foo
中定义 namespace detail
{
int Foo:var = 0;
}
。
{{1}}
如果没有明确的类封闭命名空间,则全局范围是它的封闭命名空间。
答案 1 :(得分:0)
这两个问题归结为一件事,即“你必须在实现文件中明确地为类中使用的静态数据成员提供定义”。
答案 2 :(得分:0)
1)在我的cpp的第一行,如果我只写&#34; Logger :: instance_ = nullptr;&#34;然后我收到一个错误。由于它已经在标题中声明,为什么我需要再次提到instance_是一个指针?
因为您需要能够定义静态变量而不首先声明,所以 C ++ 需要类型 定义中的信息以及声明。
2)为什么我不能将头文件中的instance_初始化为&#34;静态Logger * instance_ = nullptr;&#34;?
因为您不希望在包含标题的每个文件中都包含相同变量的副本。整个程序中应该只有一个定义,但每次访问时都需要声明。