类的静态成员变量初始化问题

我们都知道类的静态成员变量必须在类外初始化,不仅如此,类的静态成员变量最好在源文件中初始化,而不能在头文件初始化,否则,编译的时候就会报错"symbol multiply defined".
举例:

/*--testA.h--*/
class A
{
public:
    void testB();
private:
    struct B
    {
        int getStatic();
        void addStatic();
        static int seq; //static member variable
        int num;
    };
    //int A::B::seq = 0; //error, must be defined in cpp file
};
//int A::B::seq = 0; //error, must be defined in cpp file
#include "test30-static-member.h"

void A::testB() {
        B b[2];
        b[0].addStatic();
        std::cout << b[0].getStatic() << std::endl;
        b[1].addStatic();
        std::cout << b[1].getStatic() << std::endl;
    }
int A::B::seq = 0; //right
/*--main.cpp--*/
#include "testA.h"
//int A::B::seq = 0;  //also work
int main()
{
    A a;
    a.testB();
    return 0;
}

输出:
1
2

C++中有声明(declare)和定义(define)的概念,int A::B::seq = 0;与其叫做初始化,叫做定义更准确, 而结构体中的这句话实际为声明。
C++中的所有变量、函数、类等都只能定义一次,可以声明多次。 如果把int A::B::seq = 0;放到头文件中,头文件被多次include, 则可能会导致变量被多次声明, 因此不可行。

??
declare: 编译期告诉编译器变量的名字和类型
define: 链接的时候告诉变量存放位置,函数实体等。
??

根据评论提醒,static const的成员变量可以在类内初始化, 但仅限于整型和enum型。

总结:

In C++11, non-static data members, static constexpr data members, and static const data members of integral or enumeration type may be initialized in the class declaration.

struct X {
    int i=5; // ok
    const float f=3.12f; // ok
    static const int j=42; // ok
    static constexpr float g=9.5f; //ok
    static const double d = 1.23; // error
    static const char* cstr = "FOO"; // error
    struct FooT { int i; };
    static const FooT foo; // ok
};

https://stackoverflow.com/questions/9141950/initializing-const-member-within-class-declaration-in-c
https://stackoverflow.com/questions/19575258/why-must-non-integral-static-data-members-initialized-in-the-class-be-constexpr

One of the reasons why this was the case prior to C++11’s addition of constexpr was the standard did not specify how floating points were to be implemented (it is left to the processor/architecture - for example, when you say float x = 1.6f, it is actually 1.6000000000024 on most systems).

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值