

c++中的静态成员变量
source link: https://www.tlanyan.me/static-member-in-cpp/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

转载请注明文章出处: https://tlanyan.me/static-member-in-cpp
C++的 static
关键字可修饰 类
成员变量/方法,表示变量/方法不从属于特定对象,而是属于类的。仔细琢磨静态成员变量,会发现其与C++的方式既相容也矛盾,具有特殊性。
先说相容的一面。·C/C++·有声明和定义的说法:声明给出签名,定义给出具体实现。对 类型
而言, 声明
不一定能知道其对象占用空间大小,但根据 定义
肯定能确定内存占用。说静态成员与C++方式是相容的,因为其 初始化方式
与方法的定义一致。下面是一个例子:
// Foo.hpp namespace tlanyan { // 类声明和定义 class Foo { private: // 声明并定义静态成员 static int value; public: // 方法声明 void increaseValue(); int getValue() const; }; } // Foo.cpp namespace tlanyan { // 静态成员变量初始化 int Foo::value = 0; // 类方法定义 void Foo::increaseValue() { ++ value; } int Foo::getValue() { return value; } }
相对于相容点,静态成员变量更多展现出怪异的一面,以下是个人总结:
-
静态成员不能在类中初始化;非静态成员可直接初始化,静态成员在声明的同时也给出了定义,但就是不能在类中定义处直接初始化。辅以
const
的静态成员可以直接初始化,但那是const
的能力而非static
所有; -
对静态成员初始化,需要在类之外重新定义一次;如上例所示,静态成员初始化的形式如同其定义,需加上类型信息
int
;好处时保证只能初始化一次,缺点则是繁琐的重新定义; -
初始化时不受访问修饰符限制;
private
类型的静态成员可直接访问并赋值; -
静态成员初始化时可调用函数,并且可以直接调用
所属类的私有函数
;
其中第4点比较重要。在不支持C++11的编译器上,要完成静态 map
成员,就不得不借助函数返回:
#include <map> // 类定义 class Foo { private: std::map<const char*, int> maps; ... } // 静态成员初始化 std::map<const char*, int> Foo::maps = Foo::initMap(); // 或者使用全局函数 std::map<const char*, int> Foo::maps = initMap();
C++11
引入了统一初始化和 lambda
表达式,初始化的写法更为简单:
// 统一初始化 std::map<const char*, int> Foo::maps { {"a", 31}, {"b", 32} }; // lambda表达式方式 std::map<const char*, int> Foo::maps = [] { map<const char*, int> _map; _map.insert(map<const char*, int>::value_type("a", 31)); _map.insert(map<const char*, int>::value_type("a", 32)); return _map; }();
静态成员的这些异常行为很容易联想到 全局变量
,两者有许多相通的地方:在程序启动前完成初始化,在程序终止后销毁;存放的地方都是静态存储区而非堆栈;通过名字空间操作符获取值;在非函数块内通过函数调用或者lambda表达式完成初始化…
虽然各种面向对象编程语言都有静态变量,并且使用比例不低。但从 面向对象
的角度,静态成员是另一种形式的全局变量,其破坏了隔离和封装,增加了类之间的耦合,让测试变得更困难。实际编程中,应当慎用全局变量,并收紧其访问权限。
所以本质上静态成员也是全局变量,只是归属到特定类的名下。
Recommend
-
128
Java中方法的重写与成员变量的隐藏-51CTO.COM Java中方法的重写与成员变量的隐藏 作者:Hollis 2017-09-30 09:10:21 这篇文章讨论了Java面向对象概念中一个基本的概念–Field Hiding(隐...
-
38
前言 在阅读 TypeScript 文档的时候,经常会看到 类的静态属性 或者类的 类的实例属性 等名词,阅读其他篇章可能会出现另一个 类的静态成员 之类的名词。 把文档中的名词提取出来,分析后就可以发现:这些名词就是称呼多,理解起来还是很简单的。 版本说明
-
62
iOS中实例变量、成员变量和属性变量的区别我叫Vincent0.8932019.06.23 23:44:12字数 736阅读 975
-
11
C++ 静态成员与成员函数链接错误
-
6
类、对象、对象内存图、局部变量与成员变量、private修饰符、this、封装笔记发布于 46 分钟前是对一类具有共同属性和行为的事物的抽象。1、属性----成员变量(...
-
23
求问有没有方法能将调用类成员变量的函数转成类外的函数指针?-CSDN论坛使用std::function 把类成员函数指针转换为普通函数指...作者:倾夜·陨灭星尘一.什么是...
-
5
Android static静态成员变量的使用误区 – Android开发中文站你的位置:Android开发中文站 > Android开发 >
-
6
一、双重身份 如下定义了一个 School 结构体: typedef struct School { int a; int b; }SCHOOL_S; SCHOOL_S stSch; 下面我们来输出一下 stSch 以及成员变...
-
7
PriorityQueue源码-成员变量解析 精选 原创 知识浅谈 2022-10-14 10:08:59...
-
5
掌握C/C++中的静态变量与静态成员! 作者:C语言小新 2023-10-07 15:53:05 静态变量只会初始化一次,但可以多次赋值。它们在程序主函数执行之前已经由编译器分配好了内存空间。这意味着它们的初始化发生在程序的启...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK