C++11类内static成员变量声明与定义
众所周知,将⼀个类内的某个成员变量声明为static型,可以使得该类实例化得到的对象实现对象间数据共享。实例化类和实例化对象
在C++中,通常将⼀个类的声明写在头⽂件中,将这个类的具体定义(实现)写在cpp源⽂件中。
因此,就引出了static成员变量的声明与定义问题:
1. 如果⼀个类内成员变量是static的,且需要将之设定为常量(const),那么这个变量声明与初始化均可写在头⽂件内。
举个例⼦:
1// Scanner.hpp
2class Scanner {
3public:
4const static int MAX_SIZE = 0xFFFF;
5    ...
6 };
这⾥直接将MAX_SIZE声明与定义写在了头⽂件。这很好理解,编译器在为这个类分配内存空间的时候,已经知道了这个类内变量⽆需为每个对象“拷贝”⼀份(因为它是static的),并且⼜知道了它在程序运⾏过程中的值保持不变(因为它是const的),那么就可以直接将其处理。因此头⽂件内的类声明实现信息已经⾜够,从⽽这样的写法是合理的。
需要注意的是,不能在头⽂件内声明const static成员变量,⽽在具体源cpp⽂件内实现其初始化。因为这样编译器需要根据具体的实现⽂件来确定该成员变量的初始值,若实际应⽤中没有相应的实现⽂件(源cpp⽂件)来对这个成员变量实现初始化,则编译器⽆法明确意图,从⽽⽆法完成编译。
2.如果⼀个类内成员变量是static的,但不需要将其设定为常量(const),那么这个变量声明于头⽂件内,初始化(定义/实现)写在对应的cpp源⽂件中。
举个例⼦:
1// Scanner.hpp
2class Scanner {
3public:
4static int line;
5    ...
6 };
// Scanner.cpp
#include "Scanner.hpp"
int Scanner::line = 1;
...
这样的实现⽅式给了类实现者⼀种相对的⾃由。这样就可以针对不同的实现⽂件实现不同的类内static字段初始化。
⽐如有两个Scanner实现⽂件: Scanner1.cpp 和 Scanner2.cpp,那么这两个源⽂件分别#include "Scanner.hpp",就可以分别实现各⾃的类内line值初始化。当然,在实际应⽤时,切不可同时使⽤Sca
nner1和Scanner2,因为这样会发⽣符号表重定义冲突(因为两个cpp⽂件均实现了Scanner,符号表内重复填充属性字段)。
需要注意的是,此时不能将上述line的初始化写在头⽂件(Scanner.hpp)⾥。道理类似,因为编译器发现这个字段并不是const的,也就是说这个字段可以被不同的实现⽂件(cpp⽂件)来具体确定其初始值,那么编译器就不负责在声明阶段对其实现初始化,因此在头⽂件内初始化⼀个类内⾮const的static成员变量是⾮法的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。