众所周知,将一个类内的某个成员变量声明为static型,可以使得该类实例化得到的对象实现对象间数据共享。

在C++中,通常将一个类的声明写在头文件中,将这个类的具体定义(实现)写在cpp源文件中。

因此,就引出了static成员变量的声明与定义问题:

1. 如果一个类内成员变量是static的,且需要将之设定为常量(const),那么这个变量声明与初始化均可写在头文件内。

举个例子:

 // Scanner.hpp
class Scanner {
public:
const static int MAX_SIZE = 0xFFFF;
...
};

这里直接将MAX_SIZE声明与定义写在了头文件。这很好理解,编译器在为这个类分配内存空间的时候,已经知道了这个类内变量无需为每个对象“拷贝”一份(因为它是static的),并且又知道了它在程序运行过程中的值保持不变(因为它是const的),那么就可以直接将其处理。因此头文件内的类声明实现信息已经足够,从而这样的写法是合理的。

需要注意的是,不能在头文件内声明const static成员变量,而在具体源cpp文件内实现其初始化。因为这样编译器需要根据具体的实现文件来确定该成员变量的初始值,若实际应用中没有相应的实现文件(源cpp文件)来对这个成员变量实现初始化,则编译器无法明确意图,从而无法完成编译。

2.如果一个类内成员变量是static的,但不需要将其设定为常量(const),那么这个变量声明于头文件内,初始化(定义/实现)写在对应的cpp源文件中。

举个例子:

 // Scanner.hpp
class Scanner {
public:
static int line;
...
};
// Scanner.cpp
#include "Scanner.hpp" int Scanner::line = ;
...

这样的实现方式给了类实现者一种相对的自由。这样就可以针对不同的实现文件实现不同的类内static字段初始化。

比如有两个Scanner实现文件: Scanner1.cpp 和 Scanner2.cpp,那么这两个源文件分别#include "Scanner.hpp",就可以分别实现各自的类内line值初始化。当然,在实际应用时,切不可同时使用Scanner1和Scanner2,因为这样会发生符号表重定义冲突(因为两个cpp文件均实现了Scanner,符号表内重复填充属性字段)。

需要注意的是,此时不能将上述line的初始化写在头文件(Scanner.hpp)里。道理类似,因为编译器发现这个字段并不是const的,也就是说这个字段可以被不同的实现文件(cpp文件)来具体确定其初始值,那么编译器就不负责在声明阶段对其实现初始化,因此在头文件内初始化一个类内非const的static成员变量是非法的。

C++11类内static成员变量声明与定义的更多相关文章

  1. 类的static成员变量和成员函数能被继承吗

    1.   父类的static变量和函数在派生类中依然可用,但是受访问性控制(比如,父类的private域中的就不可访问),而且对static变量来说,派生类和父类中的static变量是共用空间的,这点 ...

  2. c++ 类内static成员初始化

    类内部的static成员,除了为const static 且为整数类型(int char bool)可在类内部初始化. 其他的都建议在对应的cpp文件中进行初始化. test.h #ifndef TE ...

  3. 【C++】const,static和static const类型成员变量声明及其初始化

    1)const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间 void f1() { ; cout<<x<<endl; ...

  4. static 成员变量、static 成员函数、类/对象的大小

    一.static 成员变量 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量.比如说统计某种类型对象已创建的数量. 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量 ...

  5. C++ static、const和static const类型成员变量声明以及初始化

    C++ static.const和static const 以及它们的初始化 const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间. sta ...

  6. android 20 Intnet类重要的成员变量

    Intnet类重要的成员变量: <intent-filter> <action android:name="android.intent.action.MAIN" ...

  7. 测试 Java 类的非公有成员变量和方法

    引言 对于软件开发人员来说,单元测试是一项必不可少的工作.它既可以验证程序的有效性,又可以在程序出现 BUG 的时候,帮助开发人员快速的定位问题所在.但是,在写单元测试的过程中,开发人员经常要访问类的 ...

  8. C++中的static 成员变量的一些注意点

    C++中的static成员变量主要用来为多个对象共享数据 例: #include <iostream> using namespace std; class Student{ public ...

  9. java static成员变量方法和非static成员变量方法的区别

    这里的普通方法和成员变量是指,非静态方法和非静态成员变量首先static是静态的意思,是修饰符,可以被用来修饰变量或者方法. static成员变量有全局变量的作用       非static成员变量则 ...

随机推荐

  1. Redis-消息

    Redis 发布订阅(实际开发不使用) Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图 ...

  2. 移动端 vue + mintUI 实现头部页签切换,按需加载~

    记录~记录~~有时候,我们会遇到一个页面有两个页签切换需求,但是为了避免同时加载两个页面,我们要做到的就是当前进入的是那个页面,就先加载哪一个页面,并且也不会造成浏览器地址的变化.一开始我使用的方法是 ...

  3. C/C++ 传递信息给Java

    #开始 今天有人问我C++怎么给Java传递消息 大概需求是 用C++写了一个窗口 需要把编辑框里面的东西传递给Java做处理 #解决过程 我现在能想到的有三个简单的方法 1. Socket编程 通过 ...

  4. 洛谷P1734 最大约数和(01背包)

    题目描述 选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大. 输入格式 输入一个正整数S. 输出格式 输出最大的约数之和. 输入输出样例 输入 #1 11 输出 #1 9 说 ...

  5. Cookie API介绍

    一.Java提供的操作Cookie的API Java中的javax.servlet.http.Cookie类用于创建一个Cookie Cookie类的主要方法 No. 方法 类型 描述 Cookie( ...

  6. 如何隐藏php和apache头信息

    去掉 X-Powered-By 只需要修改php.ini 中 expose_php = On 改成expose_php = Off 隐藏 Apache 版本信息,修改/etc/httpd/conf/h ...

  7. C语言:求n(n<10000)以内的所有四叶玫瑰数。-将字符串s1和s2合并形成新的字符串s3,先取出1的第一个字符放入3,再取出2的第一个字符放入3,

    //函数fun功能:求n(n<10000)以内的所有四叶玫瑰数并逐个存放到result所指数组中,个数作为返回值.如果一个4位整数等于其各个位数字的4次方之和,则称该数为函数返回值. #incl ...

  8. websocket 无法查看Data

    websocket 是浏览器新的信息传输协议,记录一些遇到的问题: 调试相关: websocket 连接以后可以在Chrome tools 中的network下看到,如图 要查看通信内容可以选中点击f ...

  9. python numpy的var std cov研究

    var:表示方差, 即各项-均值的平方求和后再除以N , std:表示标准差,是var的平方根. cov:协方差 ,与var类似,但是除以(N-1) import numpy as np # 构建测试 ...

  10. hadoop集群启动报错: java.io.IOException: Incompatible clusterIDs

    java.io.IOException: Incompatible clusterIDs in /export/hadoop-2.7.5/hadoopDatas/datanodeDatas2: nam ...