IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 2022.7.14 C++——静态成员(关键字static) -> 正文阅读

[C++知识库]2022.7.14 C++——静态成员(关键字static)

1. 静态成员定义

由关键字static修饰类体中成员,称为类静态成员。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。静态数据成员被当作该类类型的全局对象。

2. 静态属性

在类设计中,用关键字static修饰的数据成员为静态数据成员。有该类型实例化的所有对象,共享系统为静态成员分配的一个存储空间,而这个存储空间是程序执行main函数之前分配的,在实例化对象时不再为静态成员分配空间(静态成员数据不在对象空间中)。

2.1 设计静态数据成员目的是信息共享

例:

class circle
{
private:
	double pi;
	double radius;//半径
public:
	circle(double r = 0.0) :pi(3.14), radius(r)
	{
	}
	~circle() { }
	void area() const
	{
		cout << pi * radius * radius << endl;
	}
};
int main()
{
	circle cir(10.00);
	cir.area();
	size_t sz = sizeof(cir);//typedef unsigned int size_t
	cout << sz << endl;
	return 0;
}

运行结果:
在这里插入图片描述
其中,带参的构造函数初始化时,只能circle(double r = 0.0) :pi(3.14), radius?,因为构造函数在构建对象时,调用一次构建一次,如果直接在private中写出double pi = 3.14,这样的话,每次都会去构建,因此,就需要考虑静态关键字去构建数据成员,程序变为:
在这里插入图片描述
注意:在类circle中私有部分用静态关键字static声明,然后在类外对静态成员pi进行定义,如上述程序中的double circle::pi = 3.14;
下面这个虽然是对的,但是没必要,因为前面已经用静态关键字声明过:
在这里插入图片描述
总结:
同全局变量相比,使用静态数据成员有两个优势:
①静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性;
②可以实现信息隐藏,静态成员可以是private成员,而全局变量不能。

2.2 静态数据是该类所有对象共有的

静态数据是该类所有对象所共有的,可提供同一类型的所有对象之间,信息共享或信息交换的一种方式。
静态数据成员属于整个类型,使用时可用以下格式:
类名::静态数据成员名或对象.静态数据成员名(前提是可访问符为public)。
例:

class Cat
{
private:
	static int num;
private:
	std::string _owner;
	std::string _name;
public:
	Cat(const string& ow, const string &na):_owner(ow),_name(na)
	{
		num += 1;
		cout << "Create Cat: " << num << endl;
	}
	~Cat()
	{
		num -= 1;
		cout << "Destroy Cat: " << num << endl;
	}
};
int Cat::num = 0;
int main()
{
	Cat ca("yhp", "pt");
	Cat cb("hm", "bl");
	return 0;
}

运行结果:
在这里插入图片描述
在这个程序中,static int num,是共有的,但是定义的话,在类外进行定义,前面只需要进行声明就行了。

2.3 静态数据成员之前没有this

在类的成员函数中使用静态数据成员,静态数据成员之前没有this。
例:

class Cat
{
private:
	static int num;
private:
	std::string _owner;
	std::string _name;
public:
	Cat(const string& ow, const string& na) :_owner(ow), _name(na)
	{
		num += 1;
		cout << "Create Cat: " << num << endl;
	}
	~Cat()
	{
		num -= 1;
		cout << "Destroy Cat: " << num << endl;
	}
	void Print() const
	{
		cout << "Owner: " << _owner << " Name: " << _name << endl;
		num += 1;
	}
};
int Cat::num = 0;
int main()
{
	Cat ca("yhp", "pt");
	ca.Print();
	Cat cb("hm", "bl");
	cb.Print();
	return 0;
}

运行结果:
在这里插入图片描述
注意,num之所以可以+=1是因为没有this指针。
静态数据成员的类型可以是其所属类型,而非static数据成员只能被声明为该类的指针。
在这里插入图片描述

2.4 总结

①设计静态数据成员目的是信息共享和信息交流;
②类的静态数据成员为所有类对象所共享,不属于某个具体的实例;
③类的静态数据成员必须在类外定义,定义时不添加static关键字,不能在构造函数的初始化列表中创建,因为每调用一次构建函数创建一次对象,但是ststic出现的时候,不管调不调用,都会有创建对象存在;
④类的静态数据成员类型是int,short,char,long long,并且是const,可以在类中直接初始化,也可以在类外初始化;如:
在这里插入图片描述
⑤在类的成员函数中使用静态数据成员,静态数据成员之前是没有this指针的;
⑥当类的静态成员为公有时,可以在外部函数使用:类名::静态数据成员名或对象.静态数据成员名,也可以在类体中定义自身的静态类型对象。

3. 静态方法

函数成员说明为静态,将与该类的不同对象无关;静态函数成员的调用,在对象之外可以采用下面的方式: 类名::函数名或对象名.函数名;
与静态数据成员相反,为使用方便,静态函数成员多为公有。
例:

class Object
{
private:
	static int num;
private:
	int value;
public:
	// Object(int val = 0) :value(val), num(val) {} error,静态属性只能在类外初始化
	Object(int val) :value(val)
	{
		num = 1;//是赋值,不是初始化
	}
	void Print()
	{
		cout << "value: " << value << " num: " << num << endl;
	}
	/*static void Show()
	{
		cout << " value: " << value << " num: " << num << endl;
	}*/
	static void fun(Object& obj)
	{
		cout << obj.value << " " << num << endl;
	}
};
int Object::num = 0;

其中静态函数没有this指针
在这里插入图片描述
静态成员函数没有this指针,因此在静态成员函数显式地使用this指针都将导致编译时出现错误,试图访问隐式使用this指针所指向的非静态数据成员也会导致编译时出现错误。
总结:
一个常规的成员函数声明描述了三件在逻辑上相互不同的事:
(1)该函数能访问类声明的私有部分
(2)该函数位于类的作用域之中
(3)该函数必须经由一个对象去激活(有一个this指针)
将一个函数声明为友元可以使它具有第(1)种属性;将一个函数声明为static可以使它只具有第一种和第二种性质;

4. static不在类中使用时的特点

(1)构建临时变量时,如
在这里插入图片描述
普通静态变量,函数中创建并且创建之后结束,而局部静态变量,在函数结束时生存期结束,但是可见性只在当前fun函数中。
(2)构建全局变量时,如
在这里插入图片描述
静态全局变量,在程序结束时生存期结束,而且只在本文件中使用,不可多文件使用,就算在另一个文件中用extern关键字,也不行,因为其可见性就在本函数;但是普通全局变量,不加静态关键字static,其他文件用extern关键字可以使用。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:02:42  更:2022-07-17 16:07:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:44:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码