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

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

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函数,是因为后者申请内存时并不调用类的构造函数。

相关文章:

  • 小红的质数数组(A组,B组)
  • C++错误Call to implicitly-deleted default constructor of ‘SerialPortConfig‘
  • 国密算法Sm2工具类--golang实现版
  • Windows逆向工程入门之MASM编程深度解析
  • Spring MVC视图解析器的定制与应用
  • 【强化学习笔记1】从强化学习的基本概念到近端策略优化(PPO)
  • Parquet 编码
  • SQL Server 中遇到的常见问题集
  • 2025学年安徽省职业院校技能大赛 “信息安全管理与评估”赛项 比赛样题任务书
  • docker-compose部署onlyoffice8.3.0并支持ssl,且支持通过nginx代理,关闭JWT配置
  • RabbitMQ系列(四)基本概念之Exchange
  • 线上服务器的文件下载到本地Windows电脑
  • hackmyvm-hero
  • Python学习第十八天之深度学习之Tensorboard
  • 网络安全和爬虫的关系
  • 网络协议 HTTP、HTTPS、HTTP/1.1、HTTP/2 对比分析
  • 算法——分治
  • Java从根上理解 ConcurrentHashMap:缓存机制与性能优化
  • 欧几里得算法
  • 计算机视觉 |解锁视频理解三剑客——SlowFast
  • 小马智行一季度营收增12%:Robotaxi收入增长两倍,预计车队规模年底到千台
  • 设甜蜜打卡点、还能当婚车,上海定制公交车变身“幸福专列”
  • 专访《风雪夜归人》导演闫锐:在舞台上表现什么是真正的活着
  • 中国首次当选联合国教科文组织1970年《公约》缔约国大会主席国
  • 中国预警机雷达有多强?可数百公里外看清足球轨迹
  • 瑞幸首度牵手成都国际非遗节,用一杯饮品将非遗之美推向全国