• C++ 如何初始化静态类成员


    我们定义如下类:

    //A.h
    class A
    {
    private:
        static const int m = 5;
        static int n;
        static vector<int> buf;
    };

    其中包含三个私有的静态类成员,C++规定const静态类成员可以直接初始化,其他非const的静态类成员需要在类声明以外初始化,我们一般选择在类的实现文件中初始化,初始化的方式是书写一遍类型的定义:

    //A.cpp
    int A::n;                 //不指定任何初始值,系统自动初始化为0
    vector<int> A::buf;       //调用vector的默认构造函数来初始化
                                //
    注意:调用默认构造函数时,不要使用括号,否则编译器将把A::buf()当做静态成员函数,
                                //但是A::buf()实际没有被声明,所以编译器将报错

     或者:

    //A.cpp
    int A::n(9);              //使用字面量9来初始化n
    vector<int> A::buf(100);  //调用vector的带参构造函数来初始化


    对于更复杂的情形 ,如没有构造函数可以调用(比如单例模式实现的类),或者需要多步骤才能完成的初始化怎么办?
    假设有一个类S实现了单例模式,S的实例是通过调用S的静态方法S::GetInstance()来获得的,现在定义一个包含S作为静态成员的类:

    //B.h
    class B
    {
    private:
        static S s;
    };

     按照前面的介绍,我们或许应该以下面这种方式初始化s:

    //B.cpp
    #include <B.h>
    S B::s;  //编译器会报错,因为S没有可以调用的构造函数

     解决方法是定义一个静态方法,负责初始化静态成员s:

    //B.h
    class B
    {
    public:
        
    static S Init();
    private:
        
    static S s;
    };

    //B.cpp
    #include <B.h>
    S B::Init()
    {
        ....
        return S::Instance();
    }
    S B::s 
    = B::Init();            //调用静态函数初始化静态成员

    上例中,为了初始化类B的静态 成员s,我们定义了一个公有的静态方法Init(),它可以很好的工作。但是,在现实的工程中,我们很可能碰到更进一步的要求,就是希望Init()仅仅作为静态变量s的初始化器使用,而不能使用在程序中别的地方,但是我们又不能把Init()声明为private,这样Init()就不能被调用来初始化s了。解决的方法是使用内部类:

    //B.h
    class B
    {
    private:
        
    class C
        {
        
    public:
            
    static S InitB();
        };
        
    static S s;
    };

    //B.cpp
    S B::C::InitB()
    {
        ....
        
    return S::Instance();
    }
    S B::s 
    = B::C::InitB();         //调用内部类的静态成员函数来初始化静态数据成员

    因为C是B的内部类,C仅在B的作用域范围内可见,如果程序的其他地方调用了B::C::InitB(),编译器将报错,因为C不可访问。 

    最后说一下,从初始化的方式可以看出来,类的静态数据成员其实就是“带类名”的全局变量。

    静态数据成员必须显式初始化,否则在类方法中操作该成员时,将报链接错误 undefined reference to `A::buf' (gcc中)

  • 相关阅读:
    redis 安装和运行
    Django:django-debug-toolbar模块
    Django 的 logging日志文件配置
    Github之利用SSH完成Git与GitHu 的绑定
    4.输出1-100内的所有偶数
    3.输出1-100内的所有奇数
    2.求1-100的所有整数的和
    1.使用while循环输出1.2.3.4.5.6.....8.9.10
    将前台JS数组序列化后提交,后台反序列化对象
    div模拟下拉框
  • 原文地址:https://www.cnblogs.com/fre2technic/p/1995044.html
Copyright © 2020-2023  润新知