【问题标题】:Confused about this aspect of Singleton pattern对单例模式的这方面感到困惑
【发布时间】:2014-11-14 05:52:32
【问题描述】:

我从网上找到的教程改编了我的 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_初始化为“static Logger *instance_=nullptr;”?这样做会给我以下错误:

错误:静态数据的类内初始化需要“constexpr” 非整数类型的成员‘Logger* Logger::instance_’ [-fpermissive] 静态记录器*instance_=nullptr; ^

谢谢!

【问题讨论】:

    标签: c++ design-patterns singleton


    【解决方案1】:

    问题 1) 在我的 cpp 的第一行中,如果我只写Logger::instance_=nullptr;,那么我会收到一个错误。既然已经在header中声明了,为什么还要再提instance_是一个指针呢?

    来自 C++ 草案标准 N3337:

    9.4.2 静态数据成员

    5 static 命名空间范围内类的数据成员具有外部链接 (3.5)。

    与声明类似

    extern int a;
    

    在 .h 文件中并定义

    int a = 10;
    

    在 .cpp 文件中。 a 在定义时必须指定其类型。

    问题2)为什么我不能将头文件本身中的instance_初始化为“static Logger *instance_=nullptr;”?

    来自 C++ 标准草案 N3337(强调我的):

    9.4.2 静态数据成员

    2 static 数据成员在其类定义中的声明不是定义,并且可能是除 cv 限定的 void 之外的不完整类型。 static 数据成员的定义应出现在包含该成员的类定义的命名空间范围内。 在命名空间范围的定义中,static 数据成员的名称应由其类限定使用 :: 运算符命名。

    更新,以回应 OP 的评论

    假设你有:

    namespace detail
    {
       class Foo
       {
           static int var;
       };
    }
    

    Foo::var 必须在Foo 的封闭namespace 中定义。

    namespace detail
    {
       int Foo:var = 0;
    }
    

    如果一个类没有明确的封闭命名空间,则全局范围就是它的封闭命名空间。

    【讨论】:

    • 我的静态变量在这里有命名空间范围是什么意思?它与类范围不同吗?谢谢!
    【解决方案2】:

    这两个问题归结为一件事,即“您必须在实现文件中明确地为类中使用的静态数据成员提供定义”。

    【讨论】:

      【解决方案3】:

      1) 在我的 cpp 的第一行,如果我只写“Logger::instance_=nullptr;”然后我得到一个错误。既然已经在header中声明了,为什么还要提instance_是指针呢?

      因为您需要能够定义静态变量而不首先声明它们,所以C++需要类型 定义以及声明中的信息。

      2)为什么我不能在头文件本身中将instance_初始化为“static Logger *instance_=nullptr;”?

      因为您不希望在包含您的标头的每个文件中都有相同变量的副本。整个程序中应该只有一个定义,但每次访问时都需要声明

      【讨论】:

        猜你喜欢
        • 2014-11-27
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 2018-09-29
        • 1970-01-01
        相关资源
        最近更新 更多