c++中的静态成员
引言
有时候需要类的一些成员与类本身相关联,而不是与类的每个对象相关联。比如类的所有对象都要共享的变量,这个时候我们就要用到类的静态成员。
声明类的静态成员
声明静态成员的方法是使用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类型,则可以在类内初始化。
即使一个常量静态成员在类内被初始化了,通常也应该在类的外部定义一下该成员,但类外定义使不能再指定初始值,因为在类内已经提供了初始值。
静态数据成员的特殊应用场景
- 静态成员独立于任何对象,因此,静态数据成员的类型可以是他所属的类类型,非静态数据成员只能声明为他所属的类的指针或引用。
例如:
class Person{
public:
//...
private:
static Person p; //正确,静态数据成员可以是不完全类型
Person *p1; //正确:指针成员和引用可以是不完全类型
Person &p2 //正确
Person p3; //错误:数据成员必须是完全类型。
};//在此之前,class Person之后,Person类都是不完全类型,因只声明完但还没有定义完
- 可以使用静态成员作为默认实参
class Screen{
public:
Screen& clear(char = bkground);
private:
static const char bkground;
}
非静态数据成员不能作为默认实参,因为非静态数据成员属于对象,对象的值是在运行时确定的,但默认参数却是在编译时确定的,也就是说,默认参数确定时还没有真正的对象被创建,因此不能用非静态数据成员作为默认参数,否则引发错误。
声明:
c++ Basic是对《C++ Primer 第五版》的个人总结与疑难解释。
如果想要深入了解更多,请支持正版。
c++中的静态成员的更多相关文章
- 编写高质量代码改善C#程序的157个建议[优先考虑泛型、避免在泛型中声明静态成员、为泛型参数设定约束]
前言 泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能.基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型,确保了类型安全.委托 ...
- C++类中的静态成员变量与静态成员函数
最近一直看c++相关的项目,但总是会被c++类中的静态成员变量与静态成员函数的理解感觉很是模糊,不明白为什么类中要是用静态成员变量.于是在网上搜集了一些资料,自己再稍微总结下. 静态成员的概念: 静态 ...
- C#中的静态成员和非静态成员
C#的类中可以包含两种方法:C#静态方法与非静态方法.那么他们的定义有什么不同呢?他们在使用上会有什么不同呢? 让我们来看看最直观的差别:使用了static 修饰符的方法为静态方法,反之则是非静态方法 ...
- JAVA中的静态成员
//Java中的静态成员 /* *静态的成员变量是属于类的,不属于某个对象,是共享的. * 访问时可以用类名.静态属性直接访问,也可以用对象.访问,后者不提倡. * 静态的成员方法只能访问静态的成员 ...
- C++类中的静态成员变量和静态成员函数的作用
数据成员可以分为静态变量.非静态变量两种. 静态成员:静态类中的成员加入static 修饰符,即是静态成员,可以使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配 ...
- C++ 类中的静态成员变量,静态成员函数
//类中的静态成员变量,静态成员函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; /* ...
- 编写高质量代码改善C#程序的157个建议——建议33:避免在泛型类型中声明静态成员
建议33:避免在泛型类型中声明静态成员 在上一建议中,已经理解了应该将MyList<int>和MyList<string>视作两个完全不同的类型,所以,不应该将MyList&l ...
- C++ 中的静态成员函数与静态成员变量
于CSDN 2014-01-17 与静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分.如果要在类外调用公用的静态成员函数,要用类名和域运算符"∷".如Box∷volu ...
- c++类中的静态成员
静态成员和非静态成员的区别: 类静态成员用static修饰,类的静态成员属于类本身,而不属于类的某个具体对象,静态成员被类的所有对象共享,因此某个对象对静态成员(数据成员)的修改对其对象是可见的.而类 ...
- C++类中的静态成员变量与静态成员函数的使用
代码: #include <iostream> #include <string> #include <cstdio> using namespace std; c ...
随机推荐
- 插件 ExcelWrite 导出Excel格式数据/获取图层
使用ExcelWrite 插件可以导出Excel格式的数据: ExcelFile端口接 文件数据路径 最后面的是文件名,不用写格式 如果存储树形数据,需要 勾选 List To Row 选项: 附: ...
- ImportError:no mudle named 'cv2'
提供一下下载的网址:OpenCV,速度比较慢. 我的anaconda版本Python是3.6的,直接提供百度云下载: 链接:https://pan.baidu.com/s/1Xz9JrE2m-dwPv ...
- CVPR2020论文解析:实例分割算法
CVPR2020论文解析:实例分割算法 BlendMask: Top-Down Meets Bottom-Up for Instance Segmentation 论文链接:https://arxiv ...
- TVM自定义数据类型
TVM自定义数据类型 本文将介绍"自定义数据类型"框架,该框架可在TVM中使用自定义数据类型. 介绍 在设计加速器时,关键是如何近似地表示硬件中的实数.这个问题具有长期的行业标准解 ...
- HarmonyOS系统概述
HarmonyOS系统概述 系统定位 HarmonyOS是一款"面向未来".面向全场景(移动办公.运动健康.社交通信.媒体娱乐等)的分布式操作系统.在传统的单设备系统能力的基础上, ...
- A100 GPU硬件架构
A100 GPU硬件架构 NVIDIA GA100 GPU由多个GPU处理群集(GPC),纹理处理群集(TPC),流式多处理器(SM)和HBM2内存控制器组成. GA100 GPU的完整实现包括以下单 ...
- Solon Auth 认证框架使用演示(更简单的认证框架)
最近看了好几个认证框架,什么 Appache Shiro 啦.Sa-Token 啦.Spring Security啦...尤其是Spring Security,做为对标 Spring Boot &am ...
- JUC 并发编程--12, 使用AtomicInteger 实现一把锁(排队自旋锁), 代码演示
前面 使用自旋锁实现了一把锁,(请看 第5篇) volatile 三大特性: 可见性, 不保证原子性, 禁止指令重排 为了解决 volatile不保证原子性的问题, 引入了原子类, AtomicInt ...
- MySQL进阶:主主复制+Keepalived高可用
Blog:博客园 个人 概述 mysql主主复制 所谓主主复制,即双主备份,或者叫互作主从复制,每台master既是master,又是slave.这种方案,既做到了访问量的压力分流,同时也解决了单点故 ...
- MEMORY_TARGET不够时解决办法
一.报错原因:设置的memory_max_target超过了系统中设置的share memory(/dev/shm)而已. 二.解决办法:增加tmpfs的大小 三.调整tmpfs的大小(两种方法) 1 ...