引言

有时候需要类的一些成员与类本身相关联,而不是与类的每个对象相关联。比如类的所有对象都要共享的变量,这个时候我们就要用到类的静态成员

声明类的静态成员

声明静态成员的方法是使用static关键字。

static成员可以是public也可以是private的。

例如,定义一个类表示银行的账户记录:

class Account{
public:
//其他非静态函数及数据成员
//静态函数
static double get_rate(){ return interestRate; }
static void set_rate(double r){ interestRate = r; }
private:
static double interestRate;//该类的所有对象公用同一个利率
//其他static private函数
//其他非static 函数及数据成员
};

Note:

  • 类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。
  • 静态成员函数不与任何对象绑定到一起,不能在静态成员函数中使用this指针。静态成员函数不能被声明为const。

使用类的静态成员

使用作用域运算符::直接访问静态成员。

double r;
r = Account::get_rate();

虽然静态成员不属于类的任何对象,但仍然可以通过类的对象访问静态成员。

Account ac1;
Account *ac2 = &ac1;
double r = ac1.get_rate();
r = ac2->get_rate();

成员函数可以直接使用静态成员,不需要作用域运算符。

定义静态成员

定义静态成员函数

类的静态成员函数既可以定义在类的外部也可以定义在类的内部(注意定义和声明的区别)。

当在类的外部定义静态成员函数时,不能使用static关键字,static关键字只在类内部该静态成员函数的声明处使用。否则重复。

当在类的外部定义静态成员函数时,必须指明该函数所属的类,如:

class Account{
public:
//其他非静态函数及数据成员
//静态成员函数
static double get_rate(){ return interestRate; }
static void set_rate(double r){ interestRate = r; }
static void print();//静态成员函数声明
private:
static double interestRate;//该类的所有对象公用同一个利率
//其他static private函数
//其他非static 函数及数据成员
};
//定义静态函数时不需要使用static关键字,否则重复。另外指明该函数所属的类。
void Account::print(){
//要完成的工作
}

定义静态数据成员

因为静态数据成员不属于类的任何一个对象,所以他们并不是在创建类的对象的时候被定义的。不能在类的内部初始化静态数据成员,必须在类的外部定义和初始化每个静态数据成员。

double Account::interestRate = initRate();//不用static关键字

静态数据成员的类内初始化

前面提到,类的静态数据成员不应该在类的内部被初始化。但若静态数据成员同时还是constexpr类型,则可以在类内初始化。

即使一个常量静态成员在类内被初始化了,通常也应该在类的外部定义一下该成员,但类外定义使不能再指定初始值,因为在类内已经提供了初始值。

静态数据成员的特殊应用场景

  1. 静态成员独立于任何对象,因此,静态数据成员的类型可以是他所属的类类型,非静态数据成员只能声明为他所属的类的指针或引用。

    例如:
class Person{
public:
//...
private:
static Person p; //正确,静态数据成员可以是不完全类型
Person *p1; //正确:指针成员和引用可以是不完全类型
Person &p2 //正确
Person p3; //错误:数据成员必须是完全类型。
};//在此之前,class Person之后,Person类都是不完全类型,因只声明完但还没有定义完
  1. 可以使用静态成员作为默认实参
class Screen{
public:
Screen& clear(char = bkground);
private:
static const char bkground;
}

非静态数据成员不能作为默认实参,因为非静态数据成员属于对象,对象的值是在运行时确定的,但默认参数却是在编译时确定的,也就是说,默认参数确定时还没有真正的对象被创建,因此不能用非静态数据成员作为默认参数,否则引发错误。


声明:

c++ Basic是对《C++ Primer 第五版》的个人总结与疑难解释。

如果想要深入了解更多,请支持正版。

最新文章

  1. 国内maven镜像,快的飞起
  2. (转载)FT232RL通信中断问题解决办法总结
  3. hd 2112 HDU Today
  4. ajax调用WebServices服务方法和传参调用WebServices注意事项
  5. oracle数据库的TNS配置
  6. Sonar+Hudson+Maven构建系列之一:安装Sonar
  7. shadow fight 1.6.0 内购
  8. python制作pdf电子书
  9. Codeforces 626G Raffles(贪心+线段树)
  10. python趣味 ——奇葩的全局形参
  11. python 爬虫之beautifulsoup(bs4)环境准备
  12. 谷歌浏览器运行Flash
  13. TypeError: Cannot read property 'length' of null
  14. gevent-协程用法
  15. rayleighchan实现瑞利多径衰落信
  16. MVC 下拉列表三级联动
  17. 使用Coding体验小记
  18. matlab读取excel里的数据并用imagesc画图
  19. Java_正确理解ThreadLocal
  20. 20135319zl内核模块编译报告

热门文章

  1. 将TVM集成到PyTorch
  2. 在NVIDIA(CUDA,CUBLAS)和Intel MKL上快速实现BERT推理
  3. CVPR2020:点云分析中三维图形卷积网络中可变形核的学习
  4. 简化可视SLAM应用程序的开发
  5. 用 Flutter 和 Firebase 轻松构建 Web 应用
  6. 20个提高开发效率的JavaScript技巧
  7. 使用allure工具生成测试报告(基于pytest框架)
  8. C#搞跨平台桌面UI,分别实现Windows,Mac,Linux屏幕截图
  9. WordPress安装篇(2):用宝塔面板在Windows上安装WordPress
  10. 【linux】驱动-13-阻塞与非阻塞