友元与静态成员

C++(6)C++中友元与静态成员
(一)友元

 友元是访问类私有成员的一种途径.友元包括友元函数和友元类.

1.1友元函数

 在C++中友元函数允许在类外访问该类中的任何成员,就像成员函数一样,友元函数用关键字friend说明.友元函数可以通过对象访问所有成员,私有和保护成员也一样.

1.1.1将非成员函数声明为友元函数

定义一个日期类:将函数disp()声明为类Date的有元函数

class Date{
  public:
    Date(){} //构造函数
    Date(int year,int month,int day);//构造函数
    friend void disp(const Date& d);//声明函数disp()为类Date的有元函数
  private:
    int _year;
    int _month;
    int _day;
};

Date::Date(int year,int month,int day):_year(year),_month(month),_day(day){}

void disp(const Date& d){
	std::cout<<d._year<<"年 "<<d._month<<"月 "<<d._day<<"日"<<std::endl;
}

int main()
{
	Date d1(2020,12,19);
	disp(d1);
	return 0;
}

在这里插入图片描述

1.1.2将成员函数声明为友元函数

一个类的成员函数作为另一个类的友元

class Date; //对类Date的提前引用声明
class Time{
  public:
    Time(){}
    Time(int hour,int minute,int second);
    void dispDateTime(Date& d);//类Time的成员函数
  private:
    int _hour;
    int _minute;
    int _second;
};
class Date{
  public:
    Date(){}
    Date(int year,int month,int day);
    friend void Time::dispDateTime(Date& d);
  private:
	int _year;
	int _month;
	int _day;
};
Time::Time(int hour,int minute,int second):_hour(hour),_minute(minute),_second(second){}
void Time::dispDateTime(Date& d){
	std::cout<<d._year<<"年 "<<d._month<<"月 "<<d._day<<"日 ";
	std::cout<<_hour<<"时 "<<_minute<<"分 "<<_second<<"秒"<<std::endl;
}
Date::Date(int year,int month,int day):_year(year),_month(month),_day(day){}
int main()
{
	Date d1(2020,12,19);
	Time t1(12,30,59);
	t1.dispDateTime(d1);
	return 0;
}

  • 一个类的成员函数作为另一个类的成员函数时,必须先定义这个类.类Time的成员函数为类Date的友元函数,则先定义Time类.并且在声明友元函数时,要加上成员函数所在的类名: friend void Time::dispDateTime(Date& d);
  • class Date为提前引用声明
    在这里插入图片描述
1.1.3插入和提取运算符的重载友元函数

 类类型、结构体类型的输入输出

  • 重载插入运算符"<<"双目运算符
  • 左操作数:输出流类ostream的一个流对象;右操作数:系统预定义的常量/变量
  • "<<"运算符重载原型:

ostream& operator<<(ostream& 类型名);
cout<<"I LOVE C++";cout.operaor<<("I LOVE C++");

  • C++对插入运算符“<<”的功能进行补充,可以通过重载运算符“<<”实现用户自定义类型的输出.“<<”的重载格式:

ostream& operaor<<(ostream& out, 自定义类名& obj){
  out<<obj.item1;
  ...
  return out;
}

  • 重载提取运算符">>" 双目运算符
  • 左操作数:输入流类istream的一个流对象;右操作数:系统预定义的任何标准数据类型的变量
  • ">>"运算符重载原型:

istream& operator>>(istream& 类型名);

  • C++对提取运算符“>>”的功能进行补充,可以通过重载运算符“>>”实现用户自定义类型的输入.“>>”的重载格式:

istream& operaor>>(istream& in ,定义类名& obj){
  in<<obj.item1;
  ...
  return in;
}

在这里插入图片描述

1.2友元类

 整个类可以是另一个类的友元.友元类的每个成员都是另一个类的友元函数,都可以访问另一个类中的保护或私有成员.

class Time{
  friend class Date;//Date类是Time的友元类
  public:
    Time(){} //构造函数
    Time(int hour,int minute,int second); //构造函数
  private:
    int _hour;
    int _minute;
    int _second;
};
class Date{
  public:
    Date(){} //构造函数
    Date(int year,int month,int day,int hour,int minute,int second);//构造函数
    void disp();
  private:
    int _year;
    int _month;
    int _day;
    Time _t;
};
Time::Time(int hour,int minute,int second):_hour(hour),_minute(minute),_second(second){}
Date::Date(int year,int month,int day,int hour,int minute,int second):_t(hour,minute,second){
          _year = year;
          _day = day;
          _month = month;
}
void Date::disp(){
  std::cout<<_year<<"年 "<<_month<<"月 "<<_day<<"日 ";
  //定义为友元类后,可以访问Time类的所有成员
  std::cout<<_t._hour<<"时 "<<_t._minute<<"分 "<<_t._second<<"秒 "<<std::endl;
}
int main(){
  Date d1(2020,12,19,12,30,59);
  d1.disp();
  return 0;
}
  • 友元一定程度上破坏了C++的封装特性,不宜多用
  • 友元关系是单向的,不具有交换性
  • 友元关系不具有传递性在这里插入图片描述
(二)静态成员

 静态成员概念的提出:有时我们希望某一个数据成员为所有的对象所共有,实现一个类的多个对象之间的数据共享.静态成员包括静态数据成员和静态成员函数.

  • 类里面static修饰的成员,称为静态类成员
  • 类的静态成员被该类类型的所有对象所共享
    在这里插入图片描述

统计创建时间类的个数

class Date{
  public:
    Date();
    void disp();
    static void dispStatic();
  private:
    int _year;
    int _month;
    int _day;
    static int sCount; 
};
Date::Date(){
  std::cout<<"Date()"<<std::endl;
  ++sCount;
}
void Date::disp(){
  std::cout<<_year<<"年"<<_month<<"月"<<_day<<"日"<<std::endl;
}
void Date::dispStatic(){
  std::cout<<"Date count:"<<sCount<<std::endl;
}
int Date::sCount = 0;
int main(){
  Date d1,d2;
  Date::dispStatic();
  return 0;
}
  • 关于静态数据成员:
  • 静态数据成员在编译时初始化,在任何对象定义之前就存在.因此,公有的静态数据成员可以在对象定义之前被访问
  • 在类外,私有静态数据成员不能被直接访问
  • 静态数据成员的主要作用:定义类的所有对象的公用数据,如统计总数、平均数
  • 关于静态成员函数
  • 静态成员函数没有隐含this指针参数,所以可以使用类型::作用域访问符直接调用静态成员函数
  • 静态成员函数一般不访问类中的非静态成员.如果确实需要,静态成员函数只能通过对象名(或对象指针、对象引用)访问该对象的非静态成员.

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值