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 静态成员适合用来保存和类整体相关的数据,例如对象计数、共享配置等。

相关推荐
秋落风声2 小时前
内存池仿Nginx C++实现
c++·nginx
小白要努力sgy2 小时前
实时通信框架CyberRT
c++·自动驾驶·实时通讯
hansang_IR2 小时前
【记录】loj2967「COCI 2010.03.06」PROGRAM
c++·算法
霍霍的袁4 小时前
【C++初阶】缺省参数(默认参数)详细讲解
开发语言·c++·算法
楼田莉子4 小时前
C++17新特性:optional/variant/any/string_view
c++·后端·学习
I Promise344 小时前
多传感器融合&模型后处理C++工程师面试参考回答
开发语言·c++·面试
霍霍的袁4 小时前
【C++初阶】函数重载详细讲解
开发语言·c++·算法
陌路204 小时前
详解C++ 高性能网络库 muduo 的精简日志模块
开发语言·c++·php
汉克老师5 小时前
GESP6级C++考试语法知识(二十七、广度优先搜索(二、二维BFS))
c++·算法·图论·宽度优先·广度优先搜索·gesp6级·gesp六级