当前位置: 首页 > news >正文

C++ Primer 类的静态成员

欢迎阅读我的 【C++Primer】专栏

专栏简介:本专栏主要面向C++初学者,解释C++的一些基本概念和基础语言特性,涉及C++标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级程序设计技术。希望对读者有帮助!

在这里插入图片描述
在这里插入图片描述

目录

  • 7.6 类的静态成员
    • 声明静态成员
    • 使用类的静态成员
    • 静态成员的类内初始化
    • 静态成员能用于某些场景,而普通成员不能

7.6 类的静态成员

有的时候类需要它的一些成员与类本身直接相关,而不是与类的各个对象保持关联。例如,一个银行账户类可能需要一个数据成员来表示当前的基准利率。在此例中,我们希望利率与类关联,而非与类的每个对象关联。从实现效率的角度来看,没必要每个对象都存储利率信息。而且更加重要的是,一旦利率浮动,我们希望所有的对象都能使用新值。

声明静态成员

我们通过在成员的声明之前加上关键字static使得其与类关联在一起。和其他成员一样,静态成员可以是public的或private的。静态数据成员的类型可以是常量、引用、指针、类类型等。

举个例子,我们定义一个类,用它表示银行的账户记录:

class Account{
public:
void calculate(){amount+=amount*interestRate;}
static double rate(){return interestRate;}
static void rate(double);
private:
std::string owner;
double amount;
static double interestRate;
static double initRate();

类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。因此,每个Account对象将包括两个数据成员:owner和amount。只存在一个interestRate对象而且它被所有Account对象共享。

类似的,静态成员函数也不与任何对象绑定在一起,它们不包含this指针。作为结静态成员函数不能声明成const的,而且我们也不能在static函数体内使用this。这一限制既适用于this的显式使用,也对调用非静态成员的隐式使用有效。

使用类的静态成员

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

double r;
r =Account::rate();//使用作用域运算符访问静态成员

虽然静态成员不属于类的某个对象,但是我们仍然可以使用类的对象、引用或者指针来访问静态成员:

Account ac1;
Account *ac2=&ac1;
//调用静态成员函数rate的等价形式
r=ac1.rate();//通过Account的对象或引用
r=ac2->rate();//通过指向Account对象的指针

成员函数不用通过作用域运算符就能直接使用静态成员:

class Account{
public:
void calculate(){amount+=amount*interestRate;}
private:
static double interestRate;
//其他成员与之前的版本一致
};定义静态成员和其他的成员函数一样,我们既可以在类的内部也可以在类的外部定义静态成员函数。当在类的外部定义静态成员时,不能重复static关键字,该关键宇只出现在类内部的声明语句:```cpp
void Account::rate(double newRate)
{interestRate=newRate;
}因为静态数据成员不属于类的任何一个对象,所以它们并不是在创建类的对象时被定义的。这意味着它们不是由类的构造函数初始化的。而且一般来说,我们不能在类的内部初始化静态成员。相反的,必须在类的外部定义和初始化每个静态成员。和其他对象一样,-个静态数据成员只能定义一次。类似于全局变量,静态数据成员定义在任何函数之外。因此一旦它被定义,就将一直存在于程序的整个生命周期中。我们定义静态数据成员的方式和在类的外部定义成员函数差不多。我们需要指定对象的类型名,然后是类名、作用域运算符以及成员自己的名字:```cpp
//定义并初始化一个静态成员
double Account::interestRate=initRate();

这条语句定义了名为interestRate的对象,该对象是类Account的静态成员,其类型是double。从类名开始,这条定义语句的剩余部分就都位于类的作用域之内了。因此,我们可以直接使用initRate函数。注意,虽然initRate是私有的,我们也能用它初始化interestRate。和其他成员的定义一样interestRate的定义也可以访问类的私有成员。

要想确保对象只定义一次,最好的办法是把静态数据成员的定义与其他非内联函数的定义放在同一个文件中。

静态成员的类内初始化

通常情况下,类的静态成员不应该在类的内部初始化。然而,我们可以为静态成员提供const整数类型的类内初始值,不过要求静态成员必须是字面值常量类型的constexpr(参见7.5.6节,第267页)。初始值必须是常量表达式,因为这些成员本身就是常量表达式,所以它们能用在所有适合于常量表达式的地方。例如,我们可以用一个初始化了的静态数据成员指定数组成员的维度:

class Account{
public:
static double rate(){return interestRate;}
static void rate(double);
private:
static constexpr int period=30;//period是常量表达式
double daily_tbl[period];
}

如果某个静态成员的应用场景仅限于编译器可以替换它的值的情况,则一个初始化的const或constexpr static不需要分别定义。相反,如果我们将它用于值不能替换的场景中,则该成员必须有一条定义语句。例如,如果period的唯一用途就是定义daily_tbl的维度,则不需要在hccount外面专门定义period。此时,如果我们忽略了这条定义,那么对程序非常微小的改动也可能造成编译错误,因为程序找不到该成员的定义语句。举个例子,当需要把Account::period传递给一个接受const int &的函数时,必须定义period。如果在类的内部提供了一个初始值,则成员的定义不能再指定一个初始值了:

//一个不带初始值的静态成员的定义
constexpr intRccount::period;//初始值在类的定义肉提供

即使一个常量静态数据成员在类内部被初始化了,通常情况下也应该在类的外部定义一下该成员。

静态成员能用于某些场景,而普通成员不能

如我们所见,静态成员独立于任何对象。因此,在某些非静态数据成员可能非法的场合,静态成员却可以正常地使用。举个例子,静态数据成员可以是不完全类型。特别的,静态数据成员的类型可以就是它所属的类类型。而非静态数据成员则受到限制,只能声明成它所属类的指针或引用:

class Bar{
public:
// ...
private:
static Bar meml;//正确:静态成员可以是不完全类型
Bar* mem2;//正确:指针成员可以是不完全类型
Bar mem3;//错误:数据成员必须是完全类型
}静态成员和普通成员的另外一个区别是我们可以使用静态成员作为默认实参:```cpp
class Screen{
public:
//bkground表示一个在类中稍后定义的静态成员
Screen &clear(char=bkground);
private::
static const char bkground;
}

非静态数据成员不能作为默认实参,因为它的值本身属于对象的一部分,这么做的结果是无法真正提供一个对象以便从中获取成员的值,最终将引发错误。

相关文章:

C++ Primer 类的静态成员

欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...

【UCB CS 61B SP24】Lecture 4 - Lists 2: SLLists学习笔记

本文内容为重写上一节课中的单链表,将其重构成更易于用户使用的链表,实现多种操作链表的方法。 1. 重构单链表SLList 在上一节课中编写的 IntList 类是裸露递归的形式,在 Java 中一般不会这么定义,因为这样用户可能需要非常了解…...

【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin scatter plot Venn)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载画图1画图2画图3画图4画图5画图6画图7参考介绍 【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin & scatter plot & Venn) 加载R包 library…...

Linux中POSIX应用场景

Linux 提供了丰富的 POSIX(Portable Operating System Interface)标准接口,这些接口可以帮助开发者编写可移植、高效的应用程序。POSIX 标准定义了一系列系统调用和库函数,涵盖了文件操作、进程管理、线程管理、信号处理、同步机制…...

量子算法导论

重学了量子算法,不知道是温故而知新,还是之前的教材没有讲过这个概念。 如果把(图灵机)计算机比作一个查询机器,输入x通过f(x)作用得出结果,而查询的过程就是计算的过程。 中文解释…...

nasm - BasicWindow_64

文章目录 nasm - BasicWindow_64概述笔记my_build.batnasm_main.asmEND nasm - BasicWindow_64 概述 学习网上找到的demo. x64和x86的汇编源码还差挺多的。 x64的汇编代码不好写,细节整不对,程序就不运行。 如果要查为啥不运行,也要看和正向…...

SpringBoot:SSL证书部署+SpringBoot实现HTTPS安全访问

一、前言 SSL协议介于TCP/IP协议栈的第四层(传输层)和第七层(应用层)之间,为基于TCP的应用层协议(如HTTP)提供安全连接。它通过在客户端和服务器之间建立一个加密的通道,确保数据在传…...

selenium爬取苏宁易购平台某产品的评论

目录 selenium的介绍 1、 selenium是什么? 2、selenium的工作原理 3、如何使用selenium? webdriver浏览器驱动设置 关键步骤 代码 运行结果 注意事项 selenium的介绍 1、 selenium是什么? 用于Web应用程序测试的工具。可以驱动浏览…...

Spark提交任务

1、Spark提交任务到Yarn 1.1、DwKuduApp spark-submit --class com.io.etl.dwkudu.DwKuduApp \ --files /etl/etl-dwkudu/conf/doris.property,/etl/etl-dwkudu/conf/redis.property,/etl/etl-dwkudu/conf/log4j.property \ --master yarn --deploy-mode cluster \ --driver-…...

游戏引擎学习第113天

仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板:优化的基本过程 在游戏编程中,优化是一个非常重要的学习内容,尤其是想要成为专业开发者时。优化的核心是理解代码的执行速度,以及如何提升其性能。在这个阶段,已经…...

token是什么

在自然语言处理(NLP)和机器学习的背景下,token 是指模型在处理文本时的最小单位。通常,这个单位可以是单词、字符,或者词的一部分。具体来说,token 的定义取决于你使用的模型和它的分词方式。 举个例子&am…...

23. AI-大语言模型-DeepSeek赋能开发-Spring AI集成

文章目录 前言一、Spring AI 集成 DeepSeek1. 开发AI程序2. DeepSeek 大模型3. 集成 DeepSeek 大模型1. 接入前准备2. 引入依赖3. 工程配置4. 调用示例5. 小结 4. 集成第三方平台(已集成 DeepSeek 大模型)1. 接入前准备2. POM依赖3. 工程配置4. 调用示例…...

IPv6报头40字节具体怎么分配的?

目录 IPv6报头结构 字段详解 示例代码:IPv6报头的Python实现 输出示例 IPv6协议是为了解决IPv4地址耗尽问题而设计的下一代互联网协议。与IPv4相比,IPv6不仅提供了更大的地址空间,还简化了报头结构,提高了网络设备的处理效率。…...

驱动开发、移植

一、任务明确:把创龙MX8的驱动 按照我们的要求 然后移植到 我们的板子 1.Linux系统启动卡制作, sd卡 先按照 《用户手册—3-2-Linux系统启动卡制作及系统固化》 把创龙的Linux系统刷进去。 2. 把TLIMX8-EVM的板子过一遍 把刚刚烧好系统的sd卡插入 创…...

BFS与Flood Fill:算法原理、实现细节与复杂度分析

目录 1. 概述 2. BFS 的基本原理 3. Flood Fill 算法 4. BFS 实现 Flood Fill 的步骤 5. C 实现 6. 代码解析 7. 复杂度分析 8. 应用场景 总结 1. 概述 Flood Fill 算法是一种用于填充封闭区域的算法,常用于图像处理、绘图工具和游戏开发中。BFS&#xff08…...

计算机网络基础杂谈(局域网、ip、子网掩码、网关、DNS)

目录 1. 简单局域网的构成 2. IP 地址 3. 子网掩码 4. IP地址详解自定义IP 5. IP 地址详解 6. 网关 7. DNS 域名解析 8. ping 1. 简单局域网的构成 交换机是组建局域网最重要的设备,换句话说,没有交换机就没法搭建局域网 交换机不能让局域网连…...

雷龙CS SD NAND(贴片式TF卡)测评体验

一、产品概述 近期获赠雷龙科技(Longsto)推出的CS系列贴片式SD NAND存储解决方案,包含两片工业级贴片式NAND芯片(CSNP16GCR01-AOW)及全兼容转接板。该方案支持TF卡形态扩展,实现高可靠性嵌入式存储应用。 …...

【Alertmanager】alertmanager告警系统原理剖析与应用实战,应有尽有非常全面

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...

Java——权限修饰符

一、权限修饰符的继承访问规则 以下按访问范围从宽到窄排序: 修饰符同包同类同包子类同包非子类跨包子类跨包非子类public✔️✔️✔️✔️✔️protected✔️✔️✔️✔️❌默认(包级)✔️✔️✔️❌❌private✔️❌❌❌❌ 关键点&#xf…...

一周学会Flask3 Python Web开发-redirect重定向

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 前面我们学过渲染到模板页面,这个其实是一种内部的转发,浏览器地址栏地址没有变化。如果我们想重定向…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...