C++57个入门知识点_42:静态成员变量理解(static int m_nStatic;实现单独写在类外;本质是带类域的全局变量;可以不用产生对象即可访问CInteger::m_nStatic=1)

上篇C++57个入门知识点_41_初始化列表实现常成员变量和成员对象的初始化(初始化列表可以用于初始化普通成员变量/常成员变量(注意新旧编译器的写法,建议用旧的);也可以用来初始化有参数的成员对象)介绍了重要的关键字const,本篇介绍另一个重要的关键字static及在类中出现static表示什么意思?

静态成员变量总结:

  1. static int m_nStatic;(代表静态成员是在类域内),实现要单独的写在类外(cpp中,不写在.h中)
  2. 默认会用0对该成员进行初始化
  3. 静态成员变量是不同的对象(同一个类)公用的,不占用某个对象的大小
  4. CInteger::m_nStatic = 1;实现不用产生对象就可以访问静态成员变量
  5. 本质:带类域的全局变量,虽然是全局变量但是有类域的限制,解决名称限制
  6. 静态成员声明和初始化方法:
  • .h中声明: static int m_nStatic;
  • .cpp中初始化:int CInteger::m_nStatic = 123;

在C中我们学过static关键字,参考C语言基础入门48篇_44_静态局部变量、静态全局变量、静态函数(静态局部变量只被初始化一次,保留变量值、静态全局变量是加了作用域的全局变量、静态函数亦是加了作用域的函数),本篇将static修饰成员变量的情况。

1. 静态成员变量的声明及实现

我们在原先的基础上直接增加静态成员变量,会报比较有意思的错误,代码如下:

#include <iostream>
class CInteger
{
public:
	CInteger(int nNumber) {
		m_nNumber = nNumber;
	}

	int GetNumber()const;
	void SetNumber(int nNumber) {
		m_nNumber = nNumber;
	}

	//静态成员变量
	static int m_nStatic;

private:
	int m_nNumber;
};

//int CInteger::GetNumber()const
//{
//	return m_nNumber;
//}

int main()
{
	CInteger i = 1;
	
	i.m_nStatic = 123;
	i.GetNumber();
	
	return 0;
}

运行结果:报错如下
在这里插入图片描述
程序中的错误可能是编译错误或者链接错误

  • 编译错误:由于代码错误导致的编译不通过;
  • 链接错误:代码在多个Obj再组合成exe过程中发现少了某些东西,上面的代码很明显就是报的Link的链接错误。

报错和我们注释掉的函数是一样的,相当于只写了声明,没有写实现,解决思路也是一样的,给静态成员变量写上实现,并且注意:静态成员变量static int m_nStatic;(代表静态成员是在类域内)实现要单独的写在类外(cpp中,不写在.h中)

不放在.h文件中的原因: 是因为在编译器在编译时会将.h中的所有内容统统拷贝到#include下,如果放在.h文件中,静态成员变量会被重复定义

#include <iostream>
class CInteger
{
public:
	CInteger(int nNumber) {
		m_nNumber = nNumber;
	}

	int GetNumber()const;
	void SetNumber(int nNumber) {
		m_nNumber = nNumber;
	}

	//静态成员变量
	(1)实现要单独的写在类外(cpp中,不写在.h中)
	static int m_nStatic;

private:
	int m_nNumber;
};

int CInteger::GetNumber()const
{
	return m_nNumber;
}

//实现静态成员变量
int CInteger::m_nStatic;

int main()
{
	CInteger i = 1;
	i.m_nStatic = 123;
	i.GetNumber();
	return 0;
}

这样就可以编译通过了。

2. 静态成员变量的初始化

  • 初始化一般放在实现的地方
  • 若没有初始化,默认会用0对该成员进行初始化
CIntreger.cpp:
int CInteger::m_nStatic = 123;

3. 静态成员变量的性质

3.1 不同对象的成员的静态成员是共用的

静态成员变量是不同的对象(同一个类)公用的,不占用某个对象的大小。

从下图中可以看到,对象中并没有包含静态成员变量,这是为什么呢?
在这里插入图片描述
利用sizeof()查看类的大小:
在这里插入图片描述
前面我们知道:成员函数是对象所共有的,成员变量是对象私有的,按道理CInteger类中应该有两个int型数据,分别为static int m_nStaticint m_nNumber,应该占8字节。

class CInteger
{
public:
	CInteger(int nNumber) {
		m_nNumber = nNumber;
	}

	int GetNumber()const;
	void SetNumber(int nNumber) {
		m_nNumber = nNumber;
	}

	//静态成员变量
	//(1)要单独的实现写在类外(cpp中,不写在.h中)
	static int m_nStatic;

private:
	int m_nNumber;

};

很明显,静态成员变量nSize并不包含在内,下面可以通过创建两个对象,查看对象静态成员变量的地址来验证。
在这里插入图片描述

3.2 没有对象的情况下访问静态成员

既然静态成员是属于类的,属于所有对象共用,那可不可以不产生对象就访问静态成员呢?答案是可以的CInteger::m_nStatic = 1;就可以实现不用产生对象就访问静态成员。

int main()
{
	//不用创建对象就可以创建静态变量,因为它是与类相关的,一个类有一个
	//属于类而不单属于某个对象,是类公有的
	//CInteger::表示在类域范围内
	CInteger::m_nStatic = 1;
	return 0;
}

在这里插入图片描述

4. 静态成员变量的本质

#include <iostream>
#include "CIntreger.h"
int nGlobal = 3;

int main()
{
	CInteger::m_nStatic = 1;
	nGlobal = 3;
	
	return 0;
}

CInteger::m_nStatic类似于nGlobal全局变量,但是具有类域的限制。

本质:带类域的全局变量,虽然是全局变量但是有类域的限制,解决名称限制

5. VS中增加一个类的方法

VS中创建一个类,并将类的代码放入后,整体结构如下图:
在这里插入图片描述
此处加上如何在VS创建一个同名的.h及.cpp文件方法,只需两步:
在这里插入图片描述
在这里插入图片描述

6. 代码及注释

CIntreger.h:

class CInteger
{
public:
	CInteger(int nNumber) {
		m_nNumber = nNumber;
	}

	int GetNumber()const;
	void SetNumber(int nNumber) {
		m_nNumber = nNumber;
	}
	 
	//静态成员变量
	//(1)要单独的实现写在类外(cpp中,不写在.h中)
	//(2)默认会用0对该成员进行初始化
	//(3)静态成员变量是不同的对象(同一个类)公用的,不占用某个对象的大小
	//(4)本质:带类域的全局变量,虽然是全局变量但是有类域的限制,解决名称限制
	static int m_nStatic;

private:
	int m_nNumber;

};


CIntreger.cpp:

#include "CIntreger.h"

int CInteger::GetNumber()const
{
	return m_nNumber;
}

//静态成员变量的实现,若没有的话报错类似写了声明没写实现
//一般不写在.h文件中,否则会被重复调用两次报错
//若没有初始化,默认会用0对该成员进行初始化
int CInteger::m_nStatic=123;

TestC11.cpp:


#include <iostream>
#include "CIntreger.h"

int main()
{
	//不用创建对象就可以创建静态变量,因为它是与类相关的,一个类有一个
	//属于类而不单属于某个对象,是类公有的
	//CInteger::表示在类域范围内
	CInteger::m_nStatic = 1;

	//CInteger i1 = 1;
	//CInteger i2 = 1;

	//类的size只有4字节,为非静态变量的m_nNumber
	int nSize = sizeof(CInteger);
	 
	/*i.m_nStatic = 123;*/

	//分别获取两个静态变量的地址
	//int* pStatic1 = &i1.m_nStatic;
	//int* pStatic2 = &i2.m_nStatic;

	return 0;
}


7. 学习视频地址: C++57个入门知识点_42:静态成员变量理解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值