友元和static

浅谈友元和static成员


前言

在说这两个之前,我们再掰扯一下构造函数,之前我们在“浅谈六个成员函数”中提到了参数列表初始化。
在这里插入图片描述
又叫“初始化列表”。
用法:以冒号开始,接着是逗号分隔的数据成员列表,每个成员变量后面跟着放在括号中的初始值或表达式。
注:
1.每个成员变量在初始化列表中只能出现一次;
2.类中若包含:引用成员变量、const成员变量、自定义类型成员,则必须使用初始化列表进行初始化;
3.成员变量在类中的声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。


提示:以下是本篇文章正文内容

一、友元

在大学生活中,我们经常要交一些实验报告,这使我们很头疼,基本上每个宿舍都会有“那个男人”站出来写报告,然后其他人把报告改个学号姓名上交。友元就相当于这些白piao的舍友一样。
友元分为:友元函数友元类
友元提供了一种突破封装的方式,有时提供了便利,但是友元会增加耦合度,这不符合我们的“高内聚,低耦合”的思想,破坏了封装,所以友元不宜多用。

1.友元函数

例如当我们想重载“<<”或“>>”时,发现我们无法将operator<<重载成成员函数,因为cout输出流对象和成员函数隐含的this指针在抢占第一个参数的位置,this指针默认是第一个参数也就是“<<”的左操作数,但是实际使用中cout需要是第一个形参对象,才能正常使用。因此我们只能将operator<<重载为非成员函数,比如全局函数,但是这样的话又不能访问成员变量。友元函数便可以完美解决这个问题。

class Date
{
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	Date(int year, int month, int day) :m_year(year), m_month(month), m_day(day)
	{}
private:
	int m_year;
	int m_month;
	int m_day;
};
ostream& operator<<(ostream& out, const Date& d)//以引用返回可以连续输出
{
	out << d.m_year << "-" << d.m_month << "-" << d.m_day;
	return out;
}
istream& operator>>(istream& in, Date& d)
{
	in >> d.m_year;
	in >> d.m_month;
	in >> d.m_day;
	return in;
}

友元函数可以直接访问类的私有成员,它不属于任何类,需要在类里面用friend关键字声明。
在这里插入图片描述
特征:
1.友元函数可访问类的私有和保护成员,但不是类的成员函数;
2.友元函数不能用const修饰;
3.友元函数可以在类定义的任何地方声明,不受类访问限定符限制;
4.一个函数可以是多个类的友元函数;
5.友元函数的调用与普通函数调用原理相同。

2.友元类

和友元函数意义差不多,友元类的所有成员函数都可以是另一个类的友元函数,都可以访问类一个类的私有成员。

class Time
{
	friend class Date;//代表Date类是Time的友元类。
public:
	Time(int hour = 0, int minute = 0, int second = 0)
		:m_hour(hour), m_minute(minute), m_second(second)
	{}
private:
	int m_hour;
	int m_minute;
	int m_second;
};
class Date
{
public:
	Date(int year, int month, int day) :m_year(year), m_month(month), m_day(day)
	{}
private:
	int m_year;
	int m_month;
	int m_day;
	Time t;//前提是Time类中有默认构造函数(全缺省构造也为默认构造);
public:
	void DatesetTime(int hour, int minute, int second)
	{
		t.m_hour = hour;
		t.m_minute = minute;
		t.m_second = second;
	}
};

特征:
1.友元关系是单向的;
2.友元关系不能传递;

二、static

声明为static的类成员为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数静态的成员变量一定要在类外进行初始化。
剑指offer64题:求1+2+…+n,要求不能使用乘除、for、while、、if、switch等关键字及条件判断语句。

class Solution {
public:
    class Sum
    {
    public:
        Sum()
        {
            _sum += _i;
            _i++;
        }
    };
     
    int Sum_Solution(int n) {
        _i = 1;
        _sum = 0;
        Sum array[n];
        return _sum;
    }
     
    static size_t _sum;
    static size_t _i;
};
 
size_t Solution::_sum = 0;
size_t Solution::_i = 1;

特征:
1.静态成员为类对象所共享,不属于某个具体的实例;
2.静态成员变量必须在类外定义,定义时不添加static关键字;
3.类静态成员即可用类名::静态成员或者对象.静态成员访问;
4.静态成员函数没有隐藏的this指针(友元也没有且级别低于静态成员函数),不能访问任何非静态成员;
5.静态成员和类的普通成员一样,也有public、protected、private三种访问级别,也可以具有返回值;
6.普通成员函数可以调用静态成员变量及静态成员函数,而反之不能。

总结

朋友的朋友不一定是朋友;我拿你当朋友,你却不让我抄你作业。

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值