博客
关于我
C++ static静态成员 和 友元函数与友元类、内部类
阅读量:214 次
发布时间:2019-02-28

本文共 3018 字,大约阅读时间需要 10 分钟。

static静态成员变量

在成员变量前加static,该成员称为静态成员变量

static int _count;

在成员函数前加static,该函数称为静态成员函数

static int getCount()	{   		return _count;	}

代码示例

class A{   public:	static int getCount()	{   		return _count;	}private:	static int _count;};//类外定义int A::_count = 0;

static成员特性:

  1. 静态成员为所有类对象所共享,不属于某个具体的实例
  2. 静态成员变量只能在类外定义
  3. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  4. 静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值

访问static成员的方式

1、对象.static成员
2、类型::static成员

注意:static静态成员函数中,不能访问非静态成员(成员变量 + 成员函数)

友元函数

在c++中,我们常用到的cout和cin为什么可以不需要用户提供类型就可以自动打印和输入呢?那我们能不能让我们自定义类型也可以用上cout和cin呢?当然可以,其实内置类型对cout和cin都进行了操作符重载。那我们自定义类型当然也可以重载cout和cin。

class Date {   public: 	Date(int year, int month, int day) 		:_year(year)		, _month(month)		, _day(day)	{   }	void operator<<(ostream& _cout)	{   		_cout << _year << "-" << _month << "-" << _day << endl;	}private: 	int _year;	int _month;	int _day;};int main(){   	Date d(2021, 3, 4);	d.operator<<(cout);	d << cout;	return 0;}

在这里插入图片描述

虽然都能正确打印我们想要的结果,但是cout的用法并不和我们内置类型一样,我们想要做到cout << d,就必须在操作符重载函数中交换两个参数的位置,可是this在成员函数中是隐藏的第一个参数,我们无法改变它的位置,我们尝试将该函数写在类外,但是类的属性是私有的,我们无法访问到

void operator<<(ostream& _cout, Date d){   	_cout << d._year << "-" << d._month << "-" << d._day << endl;}

在这里插入图片描述

在这个基础上,我们可以将该函数变为Date类中的友元函数,友元函数不是类的成员函数,是一个普通的函数。语法规则如下:
在类中声明要成为友元函数的函数

class Date {   public: 	//友元函数的声明:规定此函数可以访问当前类的所有成员	friend void operator<<(ostream& _cout, Date d);		Date(int year, int month, int day) 		:_year(year)		, _month(month)		, _day(day)	{   }private: 	int _year;	int _month;	int _day;};void operator<<(ostream& _cout, Date d){   	_cout << d._year << "-" << d._month << "-" << d._day << endl;}

在这里插入图片描述

这样子我们就可以和内置类型一样,用cout去打印我们的自定义类型,但是这也不完全满足我们用cout去打印数据,我们打印常常是连续打印,而我们上面代码并不能满足,这就需要添加返回值,返回输出流cout,继续打印下一个数据

ostream& operator<<(ostream& _cout, Date d){   	_cout << d._year << "-" << d._month << "-" << d._day << endl;	return _cout;}

实例:

在这里插入图片描述

下面我们直接给出cin的代码

istream& operator>>(istream& _cin, Date& d){   	_cin >> d._year >> d._month >> d._day;	return _cin;}

在这里插入图片描述

注:在这里的调用cout函数的完整形式为operator<<(d1, cout),但是不存在operator<<(cout, endl),因为不存在这么个函数,cout也是一个对象,可以像普通对象调用运算符重载函数的完整形式一样cout.operator(endl)

友元类

友元类与友元函数相似,友元函数是指定友元函数后,该函数可以访问该类的私有成员。友元类是被A是B的友元类,那么A就可以访问B的私有成员但是B不能访问A的私有成员,所以友元类是单向而非双向的

内部类

在一个类的内部任何一个地方定义一个类,则定义的类为内部类。但是内部类也是一个独立的类,外部类对内部类也没有任何优越的访问权限,更不能在类外直接创建内部类。内部类其实就是更有优势的友元类。在下面代码中,类B天生就是类A的友元类,可以直接访问类A的私有成员,但是类A不能访问类B的私有成员。他们的功能区别就是内部类可以直接访问外部类的静态成员

class A{   public:	class B	{   	public:		void setA(A a)		{   			a._a = 100;			_sa = 200;		}	private:		int _b = 2;	};private:	int _a = 1;	static int _sa;};

在计算类的大小时,内部类并不参与外部类的计算、外部类也不参与内部类的计算

语法训练OJ

.

解题思路:

只要实例化一个对象,肯定是通过构造函数或者拷贝构造来创建的,我们创建一个内部类,编写它的构造函数。外部类定义一个静态累加器和一个静态自增变量。每次实例化一个对象,自增变量都加1,累机器就是之前的结果加上自增变量。

public:    class Sum    {       public:        Sum()        {               _sum += _i;            ++_i;        }    };    int Sum_Solution(int n)     {       	//静态成员声明周期长,每次都需要重置。        _i = 1;        _sum = 0;        Sum array[n];        return _sum;    }private:    static int _i;    static int _sum;};int Solution::_i = 1;int Solution::_sum = 0;

转载地址:http://dcus.baihongyu.com/

你可能感兴趣的文章
mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
查看>>
mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
查看>>
mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
查看>>
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>
Multicast1
查看>>
mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
查看>>
MySQL Cluster 7.0.36 发布
查看>>
Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
查看>>
MySQL Cluster与MGR集群实战
查看>>
multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
查看>>
mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
查看>>