c++中的静态成员变量

栏目: C++ · 发布时间: 5年前

内容简介:转载请注明文章出处:C++的先说相容的一面。·C/C++·有声明和定义的说法:声明给出签名,定义给出具体实现。对

转载请注明文章出处: 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;
  }
}

相对于相容点,静态成员变量更多展现出怪异的一面,以下是个人总结:

  1. 静态成员不能在类中初始化;非静态成员可直接初始化,静态成员在声明的同时也给出了定义,但就是不能在类中定义处直接初始化。辅以 const 的静态成员可以直接初始化,但那是 const 的能力而非 static 所有;
  2. 对静态成员初始化,需要在类之外重新定义一次;如上例所示,静态成员初始化的形式如同其定义,需加上类型信息 int ;好处时保证只能初始化一次,缺点则是繁琐的重新定义;
  3. 初始化时不受访问修饰符限制; private 类型的静态成员可直接访问并赋值;
  4. 静态成员初始化时可调用函数,并且可以直接调用 所属类的私有函数

其中第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表达式完成初始化…

虽然各种面向对象编程语言都有静态变量,并且使用比例不低。但从 面向对象 的角度,静态成员是另一种形式的全局变量,其破坏了隔离和封装,增加了类之间的耦合,让测试变得更困难。实际编程中,应当慎用全局变量,并收紧其访问权限。

所以本质上静态成员也是全局变量,只是归属到特定类的名下。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

软件框架设计的艺术

软件框架设计的艺术

[捷] Jaroslav Tulach / 王磊、朱兴 / 人民邮电出版社 / 2011-3 / 75.00元

本书帮助你解决API 设计方面的问题,共分3 个部分,分别指出学习API 设计是需要进行科学的训练的、Java 语言在设计方面的理论及设计和维护API 时的常见情况,并提供了各种技巧来解决相应的问题。 本书作者是NetBeans 的创始人,也是NetBeans 项目最初的架构师。相信在API 设计中遇到问题时,本书将不可或缺。 本书适用于软件设计人员阅读。一起来看看 《软件框架设计的艺术》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具