C++笔记:静态成员可直接通过类访问


前言


静态成员的访问方式

无论是静态成员变量还是静态成员函数,都是三种访问方式
通过对象访问
通过对象指针访问
通过类名访问

#include <iostream>
using namespace std;
class Car {

public:
	static int ms_count;
	static Car* ms_Car;
	static int getCount() {
		return ms_count;
	}
	static Car* sharedCar() {
		return ms_Car;
	}
};
int Car::ms_count = 0;
Car* Car::ms_Car = NULL;

int main()
{
	//通过对象访问
	Car car0;
	car0.ms_count = 100;
	cout << car0.getCount() << endl;

	//通过对象指针访问
	Car* p = new Car();
	p->ms_count = 200;
	cout << p->getCount() << endl;
	cout <<"p:"<< p << endl;

	//ms_Car本身是对象指针
	p->ms_Car = p;
	cout <<"p->sharedCar():"<< p->sharedCar() << endl;


	//通过类名访问
	Car::ms_count = 300;
	cout << Car::getCount() << endl;


	return 0;
}

out为

100
200
p:017DE620
p->sharedCar():017DE620
300

静态成员函数的特征

在这里插入图片描述

静态成员函数不能是虚函数

虚函数只能是非静态成员函数

因为虚函数应用于多态,多态是父类指针指向子类对象,牵扯到对象了,所以不能
在这里插入图片描述

静态成员函数内部只能访问静态成员

静态成员函数内部只能访问静态成员变量/函数,不能访问非静态成员变量/函数

因为非静态成员变量/函数在创建对象的时候才存在

而静态成员可以直接通过类调用,可能压根没有对象

下面是一些例子:

静态成员函数不能访问非静态成员变量/函数
静态成员函数不能访问非静态成员变量/函数
静态成员函数可以通过对象访问非静态成员变量
静态成员函数可以通过对象访问非静态成员变量
静态成员函数可以通过对象访问非静态成员函数
静态成员函数可以通过对象访问非静态成员函数
静态成员函数可以访问静态成员变量/函数
静态成员函数可以访问静态成员变量/函数

非静态成员函数内部可以访问静态成员

非静态成员函数只在创建对象的时候存在,不可通过类访问

在这里插入图片描述
非静态成员函数内部可以访问静态成员变量/函数

代码

#include <iostream>
using namespace std;
class Car {

public:
	int m_count;
	static int ms_count;
	static Car* ms_Car;
	static int getCount() {
		return ms_count;
		Car car0;
		car0.m_count = 10;
		car0.test();
	}
	static Car* sharedCar() {
		return ms_Car;
	}
	void test() {
		//非静态成员函数内部可以访问静态成员
		ms_count = 12;
		cout << "ms_count:"<< ms_count << endl;
		cout << "getCount():" << getCount() << endl;
	}
};
int Car::ms_count = 0;
Car* Car::ms_Car = NULL;

int main()
{

	//通过类名访问
	Car::ms_count = 300;
	cout << Car::getCount() << endl;

	Car car1;
	car1.test();

	return 0;
}

out为

300
ms_count:12
getCount():12

构造函数、析构函数不能是静态

在这里插入图片描述

当声明和实现分离时,实现部分不能带static

全局变量与静态成员变量的内存都放在全局区

代码

#include <iostream>
using namespace std;
class Car {
	
public:
	int m_count;
	static int ms_count;
	static Car* ms_Car;
};
int Car::ms_count = 0;
Car* Car::ms_Car = NULL;

int g_count;//全局变量

int main()
{

	Car car0;
	car0.m_count = 1;
	car0.ms_count = 2;

	g_count = 3;
	

	return 0;
}

汇编代码

    18: 	Car car0;
    19: 	car0.m_count = 1;
00E92138  mov         dword ptr [ebp-8],1  //赋值给栈空间 ebp是栈空间
    20: 	car0.ms_count = 2;
00E9213F  mov         dword ptr ds:[00E9C70Ch],2  //赋值给数据段
    21: 
    22: 	g_count = 3;
00E92149  mov         dword ptr ds:[00E9C714h],3  //赋值给数据段
    23: 	
    24: 
    25: 	return 0;

ds就是data segment的简写,就是数据段,即全局区

静态成员变量地址是唯一的

通过子类和父类访问的静态成员变量地址是一样的

代码

#include <iostream>
using namespace std;
class Car {
	
public:
	int m_count;
	static int ms_count;
	static Car* ms_Car;
};
int Car::ms_count = 0;
Car* Car::ms_Car = NULL;

class BigCar : public Car {

};


int main()
{
	cout << &Car::ms_count << endl;
	cout << &BigCar::ms_count << endl;
	

	return 0;
}

out为

00ACC70C
00ACC70C

汇编为【可以看出,通过父类访问静态成员变量和通过子类访问静态成员变量的汇编是一样的】

20: 	cout << &Car::ms_count << endl;
00AC1A78  mov         esi,esp  
00AC1A7A  push        0AC14E7h  
00AC1A7F  mov         edi,esp  
00AC1A81  push        0ACC70Ch  
00AC1A86  mov         ecx,dword ptr ds:[00ACD0DCh]  
00AC1A8C  call        dword ptr ds:[00ACD0A0h]  
00AC1A92  cmp         edi,esp  
00AC1A94  call        00AC12FD  
00AC1A99  mov         ecx,eax  
00AC1A9B  call        dword ptr ds:[00ACD0A8h]  
00AC1AA1  cmp         esi,esp  
00AC1AA3  call        00AC12FD  
    21: 	cout << &BigCar::ms_count << endl;
00AC1AA8  mov         esi,esp  
00AC1AAA  push        0AC14E7h  
00AC1AAF  mov         edi,esp  
00AC1AB1  push        0ACC70Ch  
00AC1AB6  mov         ecx,dword ptr ds:[00ACD0DCh]  
00AC1ABC  call        dword ptr ds:[00ACD0A0h]  
00AC1AC2  cmp         edi,esp  
00AC1AC4  call        00AC12FD  
00AC1AC9  mov         ecx,eax  
00AC1ACB  call        dword ptr ds:[00ACD0A8h]  
00AC1AD1  cmp         esi,esp  
00AC1AD3  call        00AC12FD  
  • 14
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值