c++ 静态变量 静态函数

1. 静态成员变量

1.1 简介

静态成员变量(static member variable)是属于类而不是类的实例的成员变量。它们在类的所有实例之间共享,只有一个副本存在于内存中。静态成员变量使用 static 关键字进行声明和定义,并且必须在类的外部进行初始化。

1.2 特点

  1. 静态成员变量在程序运行期间只会被初始化一次
  2. 所有对象共享相同的值:无论创建多少个对象,它们都会共享同一个静态成员变量的值。
  3. 存储于静态数据区:静态成员变量的内存分配发生在静态数据区,而不是在对象的内存中。它们在程序运行期间存在,直到程序结束。
  4. 可以通过类名和对象访问:静态成员变量可以通过类名直接访问,也可以通过对象访问。对于所有对象来说,它们都是相同的。

代码:

#include <iostream>
#include <string>using namespace std;class MyClass {
public:static int count;  // 声明静态成员变量MyClass() {std::cout << "MyClass()  Count: " << count << std::endl;count++;  // 在构造函数中对静态成员变量进行操作}static void printCount() {std::cout << "Count: " << count << std::endl;  // 在静态成员函数中访问静态成员变量}
};int MyClass::count = 0;  // 静态成员变量的定义和初始化int main() {MyClass obj1;obj1.printCount();MyClass obj2;MyClass::printCount();  // 通过类名访问静态成员函数obj1.printCount();      // 通过对象访问静态成员函数obj2.printCount();return 0;
}

运行结果:

MyClass()  Count: 0
Count: 1
MyClass()  Count: 1
Count: 2
Count: 2
Count: 2

1.3 使用场景

  1. 共享数据:如果多个对象需要共享某个值,可以将该值定义为静态成员变量。比如统计一个类的对象数量或记录全局状态等。
  2. 类常数:将常用且不会改变的值定义为静态成员变量,方便在类内外使用,并节省内存空间。
  3. 跨对象操作:当需要在多个对象之间进行协作或共享资源时,可以使用静态成员变量来实现数据传递和共享。

静态成员变量适合用于需要在多个对象之间共享数据或保存全局状态的情况下使用。

#include <iostream>
#include <string>using namespace std;class DatabaseConnection {
private:static int connectionCount; // 静态成员变量,用于记录连接数public:DatabaseConnection() {connectionCount++;std::cout << "New database connection established." << " " << connectionCount << std::endl;}~DatabaseConnection() {connectionCount--;std::cout << "Database connection closed." << " " << connectionCount << std::endl;}static int getConnectionCount() {return connectionCount;}
};int DatabaseConnection::connectionCount = 0;int main() {DatabaseConnection conn1;std::cout << "Total database connections: " << DatabaseConnection::getConnectionCount() << std::endl;std::cout << "------------------------------------ " <<std::endl;{DatabaseConnection conn2;DatabaseConnection conn3;std::cout << "Total database connections: " << DatabaseConnection::getConnectionCount() << std::endl;}std::cout << "------------------------------------ " <<std::endl;std::cout << "Total database connections: " << DatabaseConnection::getConnectionCount() << std::endl;return 0;
}

运行结果:

New database connection established. 1
Total database connections: 1
------------------------------------ 
New database connection established. 2
New database connection established. 3
Total database connections: 3
Database connection closed. 2
Database connection closed. 1
------------------------------------ 
Total database connections: 1
Database connection closed. 0

2. 静态函数

2.1 简介

静态函数(或称为静态成员函数)(static member function)是属于类而不是对象的成员函数。它们通过在函数声明前面使用 static 关键字进行标识。

2.2 特点

  1. 静态函数可以直接通过类名调用,无需创建类的对象。
  2. 静态函数不能访问非静态成员变量和非静态成员函数,因为它们没有隐式的 this 指针。
  3. 静态函数不能被声明为虚函数,因为虚函数需要动态绑定。
  4. 静态函数的作用范围限定在所属的类中,无法直接访问类的私有成员,除非它们是该类的友元函数。

2.3 使用场景

  1. 实现工具函数或辅助功能
    静态函数常用于实现一些与类的状态无关的工具函数或辅助功能。例如,计算两个整数之和可以使用一个静态函数:
#include <iostream>class MathUtils {
public:static int max(int a, int b) {return (a > b) ? a : b;}static int min(int a, int b) {return (a < b) ? a : b;}
};int main() {int num1 = 10;int num2 = 5;int maximum = MathUtils::max(num1, num2);  // 使用静态函数计算最大值int minimum = MathUtils::min(num1, num2);  // 使用静态函数计算最小值std::cout << "Maximum: " << maximum << std::endl;std::cout << "Minimum: " << minimum << std::endl;return 0;
}

通过使用静态函数,可以将一些通用的功能与类相关联,而无需创建类的实例。这样可以提高代码的可读性和可维护性。
2. 访问私有静态成员变量
如果想在类的外部访问私有静态成员变量,可以通过公有的静态成员函数来实现。这样做可以控制对私有数据的访问,并提供统一接口。

代码:

class Counter {
private:static int count_;public:static void increment() {count_++;}static int getCount() {return count_;}
};int Counter::count_ = 0;int main() {Counter::increment();Counter::increment();// 输出结果为2std::cout << Counter::getCount() << std::endl;return 0;
}
  1. 创建单例模式
    静态函数常用于创建单例模式,确保只有一个实例被创建并全局访问。
class Singleton {
private:static Singleton* instance_;// 私有构造函数,禁止外部创建对象Singleton() {}public:static Singleton* getInstance() {if (instance_ == nullptr) {instance_ = new Singleton();}return instance_;}
};Singleton* Singleton::instance_ = nullptr;int main() {Singleton* s1 = Singleton::getInstance();Singleton* s2 = Singleton::getInstance();// 输出结果为1,说明只有一个实例被创建std::cout << (s1 == s2) << std::endl;return 0;
}
  1. 在某些设计模式中,如工厂模式、策略模式等,用于创建对象或执行特定算法。
    静态函数还常用于实现工厂方法模式,即通过静态函数创建类的实例并返回。
#include <iostream>class Shape {
public:virtual void draw() = 0;static Shape* createShape(int type);// 其他成员函数...
};class Circle : public Shape {
public:void draw() {std::cout << "Drawing a circle." << std::endl;}
};class Rectangle : public Shape {
public:void draw() {std::cout << "Drawing a rectangle." << std::endl;}
};Shape* Shape::createShape(int type) {if (type == 1)return new Circle();else if (type == 2)return new Rectangle();elsereturn nullptr;
}int main() {Shape* shape1 = Shape::createShape(1);  // 使用静态函数创建圆形Shape* shape2 = Shape::createShape(2);  // 使用静态函数创建矩形shape1->draw();shape2->draw();delete shape1;delete shape2;return 0;
}
  1. 在多线程编程中,可以将静态函数作为线程入口点。

总结,静态函数是属于类而不是对象的成员函数,并且其调用方式和访问权限有所限制。适合在不依赖于特定对象状态或需要全局可访问性的情况下使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/103533.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网工笔记整理:策略工具Filter-policy的使用

一、概述 Filter-Policy&#xff08;过滤-策略&#xff09;是一个很常用的路由信息过滤工具&#xff0c;能够对接收、发布、引入的路由进行过滤&#xff0c;可应用于IS-IS、OSPF、BGP等协议。 Filter-policy在距离矢量路由协议中的应用 filter-policy import&#xff1a;不发…

Springboot引入jasypt实现加解密

一、前言 有时在实际应用中&#xff0c;我们可能需要使用到一些秘钥&#xff0c;针对某些资源文件中的内容通常情况下是明文显示&#xff0c;安全性就比较低一些&#xff0c;比如redis登陆密码以及第三方的密钥等等一览无余&#xff0c;这时就可以使用jasypt来实现加解密。 二…

提高企业竞争力的秘密武器—奇高智能呼叫中心系统

在现代商业竞争日益激烈的时代&#xff0c;企业如何提高自身的竞争力是所有企业家和管理者必须思考的问题。而奇高智能呼叫中心系统可以说是提高企业竞争力的秘密武器之一。 奇高智能呼叫中心系统作为一种基于云计算技术的新型客户服务系统&#xff0c;具有自动分配、多渠道服…

行业追踪,2023-10-11

自动复盘 2023-10-11 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

Linux进程概念(二)--进程状态进程优先级

继上回书Linux进程概念&#xff08;一&#xff09;&#xff0c;我们初步了解了进程的一些相关概念以及如何创建和查看进程&#xff0c;对其原理和一些进程现象进行了分析和解释&#xff0c;那么今天&#xff0c;我们学习下一个进程知识-进程概念。 目录 1.操作系统的进程状态 …

Java List 中存不同的数据类型

在最近的实践中&#xff0c;有人突然问了一个问题&#xff1a; 在 Java 的 List 中可以存不同的数据类型吗&#xff1f; 这个问题突然给问到了&#xff0c;我们都知道 Java 中的 List 中存的是对象&#xff0c;通常我们定义都会这样的定义&#xff1a; List<String> t…

SRC实战-cookie注入漏洞

目录 谷歌语法-信息收集 cookie注入 实战演示 信息收集 SQL注入判断 查找字段数 爆破表名 输出结果 总结 本文由掌控安全学院 - 小博 投稿 谷歌语法-信息收集 1.查找带有ID传参的网站&#xff08;可以查找sql注入漏洞&#xff09; inurl:asp idxx 2.查找网站后台&…

游戏行业该如何应对DDoS攻击问题呢?

当发现游戏服务器有受到攻击情况&#xff0c;可以通过添加防御类产品如:高防IP来解决遇到的攻击情况&#xff0c;通过DNS域名解析&#xff0c;高防IP将替代源站服务器IP对外提供在线互联网业务&#xff0c;所有业务流量都将牵引至高防IP上进行清洗&#xff0c;干净流量回注给源…

AlGaN/GaN结构的氧基数字蚀刻

引言 宽带隙GaN基高电子迁移率晶体管(HEMTs)和场效应晶体管(fet)能够提供比传统Si基高功率器件更高的击穿电压和电子迁移率。常关GaN非常需要HEMT来降低功率并简化电路和系统架构&#xff0c;这是GaN HEMT技术的主要挑战之一。凹进的AlGaN/GaN结构是实现常关操作的有用选择之一…

华为云云耀云服务器L实例评测|华为云耀云服务器L实例评测包管理工具安装软件(六)

七、华为云耀云服务器L实例评测包管理工具安装软件&#xff1a; 根据企业级项目架构图所示&#xff0c;本章主要是安装公司企业项目的基本环境LNMP&#xff0c;相关的包管理器Composer、Node、Npm、Yarn安装&#xff0c;评测一下包管理工具安装软件是否存在问题&#xff0c;如果…

区块链技术在供应链管理中的创新应用

区块链技术以其独特的不可篡改和透明性特点&#xff0c;正在逐步改变供应链管理的传统模式。本文将探讨区块链技术在供应链管理中的创新应用及其带来的效益。 区块链技术的出现为许多行业带来了创新的可能&#xff0c;其中之一就是供应链管理。通过区块链技术&#xff0c;企业可…

RS485电路设计

引言 今天学习RS485电路的设计。 首先先来了解一下RS485电路是什么干什么。 RS485是一种串行通信协议&#xff0c;也是一种电气标准。它可以用于在远距离范围内传送数据&#xff0c;最长传输距离可以达到1200米&#xff0c;可以支持多个设备同时通信。RS485通常应用于工业自…

空间精密定位与导航VR模拟培训软件突破了时空限制

随着科技的飞速发展&#xff0c;测绘遥感技术逐渐成为地理信息获取的重要手段。然而&#xff0c;传统的测绘展示方式存在着诸多局限性&#xff0c;无法充分展现出测绘数据的精细化和多元化&#xff0c;成为为解决这一难题的有效途径。 测绘工程专业作为时下就业率爆棚的专业之一…

tomcat 问题

一、start up.bat 闪退 在命令窗口run 看看是缺少了哪个环境变量 二、控制台输出乱码 logging.properties 底部添加 java.util.logging.ConsoleHandler.encoding GBK 三、缓存不足 context.xml配置 <Resources cachingAllowed"false" cacheMaxSize"100…

学习笔记|串口与PC通信的接线|移植驱动程序|串口通信实战|STC32G单片机视频开发教程(冲哥)|第二十一集(上):串口与PC通信

目录 1.串口与PC通信的接线芯片与芯片之间的通讯&#xff1a;芯片与电脑之间的通讯&#xff1a; 2.利用实验箱示例代码移植驱动程序3.串口通信实战最小工程代码移植编译提示错误&#xff1a;undefined identifier 1.串口与PC通信的接线 上节试验是串口和电脑进行一个通信&…

C++day07(auto、lambda、类型转换、STL、文件操作)

今日任务 试编程&#xff1a; 封装一个学生的类&#xff0c;定义一个学生这样类的vector容器, 里面存放学生对象&#xff08;至少3个&#xff09; 再把该容器中的对象&#xff0c;保存到文件中。 再把这些学生从文件中读取出来&#xff0c;放入另一个容器中并且遍历输出该容…

振弦采集仪应用水坝安全监测的方案

振弦采集仪应用水坝安全监测的方案 随着工业化和城市化的快速发展&#xff0c;水资源的开发和利用越来越广泛。由于水坝在水利工程中起着至关重要的作用&#xff0c;因此对水坝进行安全监测变得越来越必要。为了实现对水坝的安全监测&#xff0c;振弦采集仪可以作为一种有效的…

ideal远程Debug部署在服务器上的服务详解

ideal远程Debug部署在服务器上的服务详解 一 简介二 ideal配置步骤第一步&#xff1a;点击Edit Configurations选项添加远程连接第二步&#xff1a;配置Remote JVM debug参数第三步&#xff1a;服务的启动参数中添加第二步生成的命令并重新启动服务第四步&#xff1a;ideal启动…

面经|快手经营分析二面

1.自我介绍 2.组织架构属于中台部门还是业务部门分析岗&#xff1f; 3.组织里面有BP的角色吗&#xff1f;BP主要负责做什么&#xff1f; 回答&#xff1a;分业务方向&#xff0c;没有BP 4.项目类和数据支持类的工作占比是都少&#xff1f; 回答&#xff1a;项目类70%&#xff0…

parseInt和Math.floor有什么不同

parseInt 和 Math.floor 有什么不同 如下代码所示 const a 2.5; const b -2.5;console.log(parseInt(a)); // 2 console.log(Math.floor(a)); // 2 console.log(parseInt(b)); // -2 console.log(Math.floor(b)); // -3parseInt(); //向0方向取整 Math.floor(); // 向下取整…