C++学习笔记26:static 静态成员

目录

一、为什么需要静态成员?

二、静态成员变量

三、静态成员变量需要类外定义

四、用静态成员变量统计对象个数

五、静态成员变量不占对象空间

六、静态成员函数

[七、静态成员函数没有 this 指针](#七、静态成员函数没有 this 指针)

八、静态成员函数可以访问静态成员

九、调用方式

[1. 通过类名调用](#1. 通过类名调用)

[2. 通过对象调用](#2. 通过对象调用)

十、小结


一、为什么需要静态成员?

在C++中,普通成员变量是属于每个对象的。

例如:

cpp 复制代码
class A {
	private:
		int _a;
}; 

如果多创建几个对象:

cpp 复制代码
A a1;
A a2;
A a3;

那么这几个对象都有自己独立的 _a。

但是有些数据不应该只属于某一个对象,应该属于整个类。

比如想统计一共创建了多少个对象,就可以使用静态成员变量。


二、静态成员变量

静态成员变量使用 static 修饰。

例如:

cpp 复制代码
class A {
	public:
		A() {
			++_count;
		}
	private:
		static int _count;
};

这里 _count 是静态成员变量。

它不属于某一个具体的对象,而是属于整个类。

也就是说:

cpp 复制代码
所有 A 类对象共享同一个 _count

三、静态成员变量需要类外定义

静态成员变量虽然在类中声明,还需要在类外定义。

cpp 复制代码
class A {
	private:
		static int _count;
}; 

int A::_count = 0;

注意:

cpp 复制代码
static int _count;

这只是声明。

cpp 复制代码
int A::_count = 0;

这才是定义和初始化。

如果只在类中声明,没有在类外定义,可能会出现来连接错误。


四、用静态成员变量统计对象个数

示例:

cpp 复制代码
#include <iostream>
using namespace std;

class A {
	public:
		A() {
			++_count;
		}
		
		A(const A& a) {
			++_count;
		} 
		
		static int GetCount() {
			return _count;
		}
		
	private:
		static int _count;
}; 

int A::_count = 0;

int main() {
	A a1;
	A a2;
	A a3(a1);
	
	cout << A::GetCount() << endl;
	
	return 0;	
}

运行结果:

cpp 复制代码
3

这里创建了 a1、a2,又用 a1 拷贝了 a3,所以构造了 3 个对象。

静态成员变量 _count 被所有对象共享,可以用来统计对象数量。


五、静态成员变量不占对象空间

普通成员变量属于对象,会影响对象大小。

但是静态成员变量属于类,存放在静态区,不存放在对象内部。

例如:

cpp 复制代码
class A {
	private:
		int _a;
        static int _count;
};

这里对象只存 _a,不存 _count。

所以静态成员变量不会增加对象的大小。


六、静态成员函数

静态成员函数也使用 static 修饰。

例如:

cpp 复制代码
class A {
	public:
		static int GetCount() {
			return _count;
		}
		
	private:
		static int _count;
}; 

静态成员函数可以通过类名直接调用。

cpp 复制代码
A::GetCount();

不需要先创建对象。


七、静态成员函数没有 this 指针

普通成员函数调用时,会隐含传递 this 指针。

但是静态成员函数不属于某一个具体的对象,所以没有 this 指针。

错误示例:

cpp 复制代码
class A {
    public:
        static void Func() {
            cout << _a << endl; // 错误
        }

    private:
        int _a;
};

因为 _a 是普通成员变量,必须依赖具体对象存在。

而静态成员函数没有 this 指针,不知道一概访问哪个对象的 _a。


八、静态成员函数可以访问静态成员

静态成员函数可以直接访问静态成员变量。

cpp 复制代码
#include <iostream>
using namespace std;

class A {
	public:
		static int GetCount() {
			return _count;
		}

	private:
		static int _count;
}; 

因为 _count 属于类,不属于某个对象,所以静态储层元函数可以访问它。

简单总结:

cpp 复制代码
静态成员函数可以访问静态成员;
静态成员函数不能直接访问非静态成员。

九、调用方式

静态成员函数有两种调用方式。

1. 通过类名调用

cpp 复制代码
A::GetCount();

这种方式更推荐,因为他能说明 GetCount 属于类本身。

2. 通过对象调用

cpp 复制代码
A a;
a.GetCount();

这种方式也可以,但不如类名调用清晰。


十、小结

本篇主要学习了C++中的 static 静态成员。

需要记住:

  1. 静态成员变量使用 static 修饰;
  2. 静态成员变量属于类,不属于某个对象;
  3. 所有对象共享一个静态成员变量;
  4. 静态成员变量需要在类外定义和初始化;
  5. 静态成员变量不占对象空间;
  6. 静态成员函数也使用 static 修饰;
  7. 静态成员函数没有 this 指针;
  8. 静态成员函数不能直接访问普通成员变量;
  9. 静态成员函数可以直接访问静态成员变量;
  10. 静态成员函数推荐通过类名调用。

static 静态成员适合用来保存和类整体相关的数据,例如对象计数、共享配置等。

相关推荐
unicrom_深圳市由你创科技21 小时前
哪些控制逻辑应该放在 PLC,哪些放在上位机?
c++
玖玥拾1 天前
C/C++ 基础笔记(十三)继承
c语言·c++·继承
ao-weilai1 天前
C++:哈希表
c++·哈希算法·散列表
汉克老师1 天前
GESP7级C++考试语法知识(二、指数函数(1、pow() 函数)
c++·指数函数·pow·gesp7级·精度误差
旖-旎1 天前
FloodFill(图像渲染)(1)
c++·算法·深度优先·力扣
汉克老师1 天前
GESP2026年3月认证C++六级真题与解析(编程题1 选数)
c++·动态规划·线性dp·gesp六级·状态转移·选与不选
有点。1 天前
C++倍增法(练习题)
c++·算法
凡人叶枫1 天前
Effective C++ 条款23:宁以 non-member、non-friend 替换 member 函数
linux·开发语言·c++·嵌入式开发
C语言小火车1 天前
什么时候用智能指针?什么时候用裸指针?
c语言·c++·学习·指针
玖玥拾1 天前
C/C++ 基础笔记(十二)友元、运算符重载
c语言·c++·运算符重载·友元