前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++】剖析static关键字&&友元

【C++】剖析static关键字&&友元

作者头像
用户11456817
发布2025-01-22 08:50:09
发布2025-01-22 08:50:09
11800
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

static,在英语单词中译为静态,静态的意思。当然,在这个从C至C++的关键词都发挥着非凡的作用的关键词的用法上,相信还是有很多小伙伴摸不着头脑,我也不例外,总是用得我抓耳挠腮,一点头绪都无。

在百度中查询,查到的也是CSDN上的种种详解,看得我也是天花乱坠,眼花缭乱。对于这种一知半解的重要知识点,我们也应该去尝试看懂,明白。所以,我在这里为大家讲叙我对其的一些理解,希望能帮到大家~

-----------------------------------------------------Begin-----------------------------------------------------

在开是介绍static关键词之前,向大家详述一个较为简易的关键词:explicit~

关键词explicit:

首先对于explicit,在C++中主要是用于修饰只有一个参数的类的构造函数,它的作用是表明该构造函数是显示的, 当然有显示的,肯定就有隐性的用来对应:关键词implicit

特性:
  • C++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。
  • 构造函数前⾯加explicit就不再⽀持隐式类型转换。
  • 类类型的对象之间也可以隐式转换,需要相应的构造函数支持。

那么在显示声明的构造函数和隐式声明的有什么区别呢?我们举一个例子来看看:

代码语言:javascript
代码运行次数:0
运行
复制
#include<iostream>
using namespace std;
class A
{
public:
	// 构造函数explicit就不再⽀持隐式类型转换
	// explicit A(int a1)
	A(int a1)
		:_a1(a1)
	{}
	//explicit A(int a1, int a2)
	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{}
	void Print()
	{
		cout << _a1 << " " << _a2 << endl;
	}
	int Get() const
	{
		return _a1 + _a2;
	}
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
public:
	B(const A& a)
		:_b(a.Get())
	{}
private:
	int _b = 0;
};
int main()
{
	// 1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3
	// 编译器遇到连续构造+拷⻉构造->优化为直接构造
	A aa1 = 1;
	aa1.Print();
	const A& aa2 = 1;
	// C++11之后才⽀持多参数转化
	A aa3 = { 2,2 };
	// aa3隐式类型转换为b对象
	// 原理跟上⾯类似
	B b = aa3;
	const B& rb = aa3;
	return 0;
}

运行结果:

explicit关键字的作用就是防止类构造函数的隐式自动转换。

在前面说explicit主要是用于修饰只有一个参数的类的构造函数,多一个参数的话则无效,但有一种情况除外,就是当除第一个参数以外的其他参数都有默认值的话,explicit有效~

接下来就来讲解一下我们的static啦~

关键字static:
关键字static是什么:

static是C/C++中的一个关键字,可以在函数和变量上使用(也就是他们的修饰符),主要作用是控制变量的存储方式和作用范围,被放在静态区中~

C语言中主要修饰的对象:局部变量,全局变量,函数~

C++中主要也是修饰的变量和函数,但叫法不同,声明为static的类成员称为类的静态成员,分为两类:

  • 用static修饰的成员变量,称之为静态成员变量
  • 用static修饰的成员函数,称之为静态成员函数
C++中static的概念:
  • 用static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进行初始化。
  • 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区
  • 用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
  • 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。
  • 非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
  • 突破类域就可以访问静态成员,可以通过类名::静态成员 或者 对象.静态成员 来访问静态成员变量和静态成员函数。
  • 静态成员也是类的成员,受public、protected、private 访问限定符的限制。
  • 静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员
  • 变量不属于某个对象,不走构造函数初始化列表。
代码语言:javascript
代码运行次数:0
运行
复制
// 实现⼀个类,计算程序中创建出了多少个类对象?
#include<iostream>
using namespace std;
class A
{
public:
	A()
	{
		++_scount;
	}
	A(const A& t)
	{
		++_scount;
	}
	~A()
	{
		--_scount;
	}
	static int GetACount()
	{
		return _scount;
	}
private:
	// 类⾥⾯声明
	static int _scount;
};
// 类外⾯初始化
int A::_scount = 0;
int main()
{
	cout << A::GetACount() << endl;
	A a1, a2;
	A a3(a1);
	cout << A::GetACount() << endl;
	cout << a1.GetACount() << endl;
	// 编译报错:error C2248: “A::_scount”: ⽆法访问 private 成员(在“A”类中声明)
	//cout << A::_scount << endl;
	return 0;
}

运行代码:

当静态成员变量变成私有时,有三种方法可以采用:

  • 通过对象.静态成员函数来访问
  • 通过类名::静态成员函数来进行访问
  • 通过匿名对象调用成员函数进行访问
static OJ题直达:

很具有教学意义的一道oj题,感兴趣的铁子可以试试哦~

求1+2+3+...+n_牛客题霸_牛客网

友元:

一开始听到这个名词的时候,感觉就很容易理解,友元友元(跟友员一样),不就是很好相处,可以跟谁都玩得来的意思吗?emm~差不多是这个意思,但又感觉不太确切,说得很准确一点,就是你愿意跟你交的这个朋友不存在任何隐私,这样就更贴切一点~

友元的概念:

友元提供了⼀种突破类访问限定符封装的方式,友元分为:友元函数和友元类,在函数声明或者类

声明的前面加friend,并且把友元声明放到⼀个类的里面。

其中友元函数又包括:全局函数做友元,成员函数做友元~

友元的特性:
  • 外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,他不是类的成员函数。
  • 友元函数可以在类定义的任何地⽅声明,不受类访问限定符限制。
  • ⼀个函数可以是多个类的友元函数。
  • 友元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员。
  • 友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。
  • 友元类关系不能传递,如果A是B的友元, B是C的友元,但是A不是C的友元。
  • 有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多⽤。

全局函数做友元的代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#include<iostream>
using namespace std;
// 前置声明,都则A的友元函数声明编译器不认识B
class B;
class A {
	// 友元声明
	friend void func(const A& aa, const B& bb);
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
	// 友元声明
	friend void func(const A& aa, const B& bb);
private:
	int _b1 = 3;
	int _b2 = 4;
};
void func(const A& aa, const B& bb)
{
	cout << aa._a1 << endl;
	cout << bb._b1 << endl;
}
int main()
{
	A aa;
	B bb;
	func(aa, bb);
	return 0;
}

在全局函数func()的前面加入friend即可访问类A和类B中的所有成员~

调试也没有问题~

做友元代码:

代码示例如下:

代码语言:javascript
代码运行次数:0
运行
复制
#include<iostream>
using namespace std;
class A
{
	// 友元声明
	friend class B;
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
public:
	void func1(const A& aa)
	{
		cout << aa._a1 << endl;
		cout << _b1 << endl;
	}
	void func2(const A& aa)
	{
		cout << aa._a2 << endl;
		cout << _b2 << endl;
	}
private:
	int _b1 = 3;
	int _b2 = 4;
};
int main()
{
	A aa;
	B bb;
	bb.func1(aa);
	bb.func1(aa);
	return 0;
}

关键点

这样class B类就可以访问class A类中全部的成员啦~

代码调试如下:

友元的内容比较易懂,铁子可以自己看看,应该就没有什么问题啦~

-----------------------------------------------------End--------------------------------------------------------

以上就是我分享的我对【C++】(剖析static关键字&&友元)理解的相关内容,蟹蟹你的阅读,希

望可以对你有所帮助~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • -----------------------------------------------------Begin-----------------------------------------------------
  • 关键词explicit:
  • 特性:
  • 关键字static:
  • 关键字static是什么:
  • C++中static的概念:
  • static OJ题直达:
  • 友元:
  • 友元的概念:
  • 友元的特性:
  • -----------------------------------------------------End--------------------------------------------------------
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档