类和对象——static修饰类的成员

news2025/2/28 14:09:41

static修饰类的成员

  • static成员
    • 1 static成员的概念
    • 2 特性

static成员

有时会有这样的需求:计算程序中创建出了多少个类的对象,以及多少个正在使用的对象。

因为构造函数和析构函数都只会调用一次,所以可以通过设置生命周期和main函数一致的计数变量进行统计。

计数变量用全局变量还会有别的问题:c++讲究封装,用全局变量可能会被不明因素修改。

#include<iostream>
#include<cstdlib>
int n, m;

class A {
public:
	A() {
		++n;
		++m;
	}
	A(A& a) {
		++n;
		++m;
	}
	~A() {
		--m;
	}
private:
};

A f(A a) {
	return a;
}

A& f1(A a) {//传引用返回
	return a;
}

//A& f1(A& a) {//传引用返回,形参也是引用
//	return a;
//}

int main() { 
	A a1;
	A a2;
	using std::cout;

	cout << n << " " << m << "\n";

	//++n;++m;//外部修改

	A();

	cout << n << " " << m << "\n";

	f(a1);
	f1(a1);

	cout << n << " " << m << "\n";

	return 0;
}

此时我们希望计数变量和类绑定,但又不想这些计数变量和成员函数一样属于公有。

1 static成员的概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数

静态成员变量一定要在类外进行初始化。因为静态成员变量属于类,所以并不通过某一对象的初始化列表(构造函数)进行初始化,需要声明和定义分离。

通过static成员变量对创建的对象个数进行统计:

#include<iostream>
using namespace std;

class A {
public:
    A() { ++_scount; }
    A(const A& t) { ++_scount; }
    ~A() { --_scount; }
    static int GetACount() { return _scount; }
private:
    static int _scount;//声明
};
int A::_scount = 0;//定义

int main() {
    cout << A::GetACount() << endl;
    A a1, a2;
    A a3(a1);
    A a4 = a1;
    cout << A::GetACount() << endl;
    return 0;
}

2 特性

  1. 静态成员所有类对象所共享,不属于某个具体的对象,存放在静态区。这就意味着空指针也能访问静态成员变量,和空指针能访问成员函数是一样的道理:看访问的数据在哪。

  2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明。

  3. 类静态成员即可用类名::静态成员或者对象.静态成员类的指针->静态成员来访问。
    例如这个案例通过NULL来访问静态成员。

#include<iostream>
using namespace std;

class A {
public:
    A() { ++_scount; }
    A(const A& t) { ++_scount; }
    ~A() { --_scount; }
    static int GetACount() { return _scount; }
    static int _scount;//声明
private:
};
int A::_scount = 0;//定义

int main() {
    cout << A::GetACount() << endl;
    A a1, a2;
    A a3(a1);
    A a4 = a1;
    cout << ((A*)(NULL))->_scount << endl;
    //将NULL强制转换为A的指针用于访问公有成元
    return 0;
}
  1. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员。
    这就意味着静态成员函数不可调用非静态成员函数,
    但非静态成员函数可以调用类的静态成员函数。
    而且因为没有this指针,也就不需要访问构造函数,对其他的静态成员变量不构成影响。

  2. 静态成员也是类的成员,受publicprotectedprivate 访问限定符的限制。

  3. 静态成员可以是数组,指针,但都要初始化。指针若存在使用alloc系列函数或关键字new申请空间,则需要在main结束前显式释放,或通过全局对象的析构函数进行空间释放。

#include<iostream>
#include<cstdlib>
using namespace std;

class A {
public:
	~A() {
		if (c)//需要加语句判断,防止被局部对象造成段错误
			free(c);
		c = NULL;
	}
	static int a[];
	static int b[10];
	static int* c;
};

int A::a[] = { 6 };
//int A::b[6] = { 1,3,5,2 };//元素数量不匹配不给编译通过
int A::b[10] = { 0 };
int* A::c = (int*)malloc(4 * 10);

A a;//全局对象调用析构函数

int main() {
	A a;
	if (A::c) {
		free(A::c);//手动释放
		A::c = NULL;
	}
	return 0;
}

static成员的应用可以通过这个OJ体现:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C) ,这个OJ将公式、位运算和递归都限制了。

但可以通过设置类的静态成员变量,并生成具有连续空间的数组来进行求和。

参考程序1:

class A{
public:
    A(){
        ++n;
        sum+=n;
    }
    static int n;
    static int sum;
};
int A::n=0;
int A::sum=0;

class Solution {
public:
    int Sum_Solution(int n) {
        A a[n];
        return A::sum;
    }
};

Nowcoder平台支持变长数组,所以可以这样声明数组:A a[n]。若平台不支持,还可以通过new关键字生成对象数组:

class A{
public:
    A(){
        ++n;
        sum+=n;
    }
    static int n;
    static int sum;
};
int A::n=0;
int A::sum=0;

class Solution {
public:
    int Sum_Solution(int n) {
        A* a=new A[n];
        int ans=A::sum;
        free(a);
        return ans;
    }
};

这里用new不用malloc函数或calloc函数,是因为后者申请内存时并不调用类的构造函数。

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

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

相关文章

MYSQL 5.7数据库,关于1067报错 invalid default value for,解决方法!

???作者&#xff1a; 米罗学长 ???个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 ???各类成品java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot&#xff0c;mysql等项目&#xff0c;源码丰富&#xff0c;欢迎咨询。 ???…

【Linux基础】Linux下的C编程指南

目录 一、前言 二、Vim的使用 2.1 普通模式 2.2 插入模式 2.3 命令行模式 2.4 可视模式 三、GCC编译器 3.1 预处理阶段 3.2 编译阶段 3.3 汇编阶段 3.4 链接阶段 3.5 静态库和动态库 四、Gdb调试器 五、总结 一、前言 在Linux环境下使用C语言进行编程是一项基础且…

浅谈HTTP及HTTPS协议

1.什么是HTTP&#xff1f; HTTP全称是超文本传输协议&#xff0c;是一种基于TCP协议的应用非常广泛的应用层协议。 1.1常见应用场景 一.浏览器与服务器之间的交互。 二.手机和服务器之间通信。 三。多个服务器之间的通信。 2.HTTP请求详解 2.1请求报文格式 我们首先看一下…

Pytest自定义测试用例执行顺序

文章目录 1.前言2.pytest默认执行顺序3.pytest自定义执行顺序 1.前言 在pytest中&#xff0c;我们可能需要自定义测试用例的执行顺序&#xff0c;例如登陆前需要先注册&#xff0c;这个时候就需要先执行注册的测试用例再执行登录的测试用例。 本文主要讲解pytest的默认执行顺序…

人大金仓KCA | 用户与角色

人大金仓KCA | 用户与角色 一、知识预备1. 用户和角色 二、具体实施1. 用户管理-命令行1.1 创建和修改用户1.2 修改用户密码1.3 修改用户的并发连接数1.4 修改用户的密码有效期 2.用户管理-EasyKStudio2.1 创建和修改用户2.2 修改用户密码2.3 修改用户的并发连接数2.4 修改用户…

【Azure 架构师学习笔记】- Azure Databricks (12) -- Medallion Architecture简介

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (11) – UC搭建 前言 使用ADB 或者数据湖&#xff0c;基本上绕不开一个架构“Medallion”&#xff0c; 它使得数据管理更为简单有效。ADB 通过…

智能证件照处理器(深度学习)

功能说明:支持常见证件照尺寸(一寸、二寸、护照等) 智能背景去除(使用深度学习模型)自定义背景颜色选择自动调整尺寸并保持比例实时预览处理效果注意:整合rembg进行抠图,使用Pillow处理图像缩放和背景替换,定义常见证件照尺寸,并提供用户交互选项。首次运行时会自动下…

C++-第十三章:红黑树

目录 第一节&#xff1a;红黑树的特征 第二节&#xff1a;实现思路 2-1.插入 2-1-1.unc为红 2-1-2.cur为par的左子树&#xff0c;且par为gra的左子树(cur在最左边) 2-1-2-1.unc不存在 2-1-2-2.unc为黑 2-1-3.cur为par的右子树&#xff0c;且par为gra的右子树(cur在最右侧) 2-…

推荐3个背景渐变色的wordpress主题

干净、清爽、背景渐变色的wordpress企业主题 ​ 服务类公司wordpress企业主题https://www.jianzhanpress.com/?p8255 红色大气的wordpress企业主题&#xff0c;适合服务行业的公司搭建企业官方网站使用。 ​ wordpress询盘型独立站主题https://www.jianzhanpress.com/?p8258…

Scrapy:隧道代理中移除 Proxy-Authorization 的原理解析

隧道代理中移除 Proxy-Authorization 的原理解析 背景 在 Scrapy 的 HTTP 下载处理中&#xff0c;当使用隧道代理&#xff08;TunnelingAgent&#xff09;时&#xff0c;会移除请求头中的 Proxy-Authorization。这个操作看似简单&#xff0c;但背后有着重要的安全考虑和技术原…

微信小程序-二维码绘制

wxml <view bindlongtap"saveQrcode"><!-- 二维码 --><view style"position: absolute;background-color: #FFFAEC;width: 100%;height: 100vh;"><canvas canvas-id"myQrcode" style"width: 200px; height: 200px;ba…

Fiddler 的安装与使用

目录 1、Fiddler 的安装2、Fiddler 的使用 1、Fiddler 的安装 通过Fiddler 官网进行下载&#xff08;下载免费的经典版本&#xff09;&#xff0c;填写用途、邮箱、国家信息即可开始下载。 Fiddler 官网下载链接 双击安装包即可进行安装&#xff0c;显示以下界面说明安装成功。…

Hadoop架构详解

Hadoop 是一个开源的分布式计算系统&#xff0c;用于存储和处理大规模数据集。Hadoop 主要由HDFS&#xff08;Hadoop Distributed File System&#xff09;、MapReduce、Yarn&#xff08;Jobtracker&#xff0c;TaskTracker&#xff09;三大核心组件组成。其中HDFS是分布式文件…

清华大学DeepSeek文档下载,清华大学deepseek下载(完成版下载)

文章目录 前言一、清华大学DeepSeek使用手册下载二、清华大学DeepSeek使用手册思维导图 前言 这是一篇关于清华大学deepseek使用手册pdf的介绍性文章&#xff0c;主要介绍了DeepSeek的定义、功能、使用方法以及如何通过提示语设计优化AI性能。以下是对这些核心内容的简要概述&…

Hadoop第2课(伪分布式集群的搭建)

jdk和hadoop安装包&#xff1a; hadoop-2.9.2.t......等2个文件官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 1、用XFTP发送hadoop安装包和jdk到/home/hadoop/目录下&#xff08;hadoop用户的主目录&#xff09; 2、解压jdk安装包到~目录 卸载jdk的命令&#xff1a;r…

使用Crawlee可破题js渲染采集数据

使用 Crawlee 实现自动化爬虫流程 1. Crawlee 简介 Crawlee 是一个强大的爬虫框架&#xff0c;用于快速构建和维护可靠的爬虫。它支持多种爬虫类型&#xff0c;包括基于 Cheerio 和 Playwright 的爬虫&#xff0c;能够高效处理静态和动态网页。 2. 项目目标 通过自动化脚本实…

Fiddler在Windows下抓包Https

文章目录 1.Fiddler Classic 配置2.配置浏览器代理自动代理手动配置浏览器代理 3.抓取移动端 HTTPS 流量&#xff08;可选&#xff09;解决抓取 HTTPS 失败问题1.Fiddler证书过期了 默认情况下&#xff0c;Fiddler 无法直接解密 HTTPS 流量。需要开启 HTTPS 解密&#xff1a; 1…

Java语法基础知识点1

目录 一、数组 1.1数组的初始化&#xff1a; 1.2数组的遍历方法&#xff1a; 1.3数组的常见使用方法&#xff1a; 二、类和对象 2.1构造方法&#xff1a; 2.2this关键字: 三、封装 3.1访问限定符&#xff1a; 3.2static关键字&#xff1a; 3.3代码块&#xff1a; 一…

【新手入门】SQL注入之盲注

一、引言 在我们的注入语句被带入数据库查询但却什么都没有返回的情况我们该怎么办? 例如应用程序返回到一个"通用的"的页面&#xff0c;或者重定向一个通用页面(可能为网站首页)。这时&#xff0c;我们之前学习的SQL注入的办法就无法使用了。这种情况我们称之为无…

python-leetcode-分割等和子集

416. 分割等和子集 - 力扣&#xff08;LeetCode&#xff09; class Solution:def canPartition(self, nums: List[int]) -> bool:total sum(nums)if total % 2 ! 0:return Falsetarget total // 2dp [False] * (target 1)dp[0] Truefor num in nums:for j in range(tar…