众所周知,将一个类内的某个成员变量声明为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. django admin后台(数据库简单管理后台)

    只需要简单的几行胆码就可以生成一个完整的管理后台 这个就是django魅力之一 创建超级用户 python manage.py createsuperuser     ----  之后会提示输入用慕名 ...

  2. zabbix监控服务部署脚本

    搭建平台脚本: #!/bin/bash #zabbix监控服务部署 #脚本使用前提:yum搭建,nginx-1.12.2源码包,zabbix-3.4.4源码包,要求源码包尽量在单一目录下,最好在默认管 ...

  3. 喵星之旅-狂奔的兔子-linux安装

    一.前言 本文演示虚拟机安装,和真机区别可能在网卡驱动上有差异. 真机环境:CentOS Linux release 7.6.1810 (Core) 虚拟机(虽然centos系统自带虚拟机软件,但是习 ...

  4. 解决tensorflow Saver.restore()无效的问题

    解决tensorflow 的 Saver.restore()无法从本地读取变量的问题 最近做tensorflow 手写数字识别的时候遇到了一个问题,Saver的restore()方法无法从本地恢复变量 ...

  5. <位运算> 任意二进制数 异或两个相同的二进制数 还是原本的值

    二进制,即0与1. 因为两个相同的二进制 异或必为0.(类似于不进位加法) 二进制里与0异或为其原本的0与1.. 可得任意二进制数 异或两个相同的二进制数 还是原本的值. 可用于交换和加密.

  6. 【前端基础之HTML】

    " 目录 一.HTML介绍 二.head内常用标签 三.body内常用标签 一.HTML介绍 1. web服务本质 from socket import socket, SOL_SOCKET ...

  7. SQLite3约束介绍

    SQLite 约束 约束是在表的数据列上强制执行的规则.这些是用来限制可以插入到表中的数据类型.这确保了数据库中数据的准确性和可靠性. 约束可以是列级或表级.列级约束仅适用于列,表级约束被应用到整个表 ...

  8. 组件向外暴露v-model绑定的参数

    <template> <div class="search-box"> <i class="icon-search">< ...

  9. cmd添加管理员账号

    net user 用户名 密码 /add net localgroup Administrators 用户名 /add

  10. ubuntu 命令记录

    1.su root  进入root模式 2.ifconfig 查看ip地址 3.ls 查看文件 4./etc/init.d/matrix-gui-2.0 stop 关闭matrix界面 5.cd /文 ...