一、友元函数
在C++中友元函数允许在类外访问该类内的任何成员,就像成员函数一样。友元的关键字为friend。
1、友元函数不是类的成员函数
2、友元函数可以通过对象访问所有成员,私有和保护都可以
class Date
{
friend void Show(const Date& d);
public:
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
void Show(const Date& d)
{
cout << d._year << "-" << d._month << "-" << d._day << endl;
}
void test()
{
Date d(2018, 2, 19);
Show(d);
}
注意:
(1)友元函数可访问类的私有成员,但不是类的成员函数
(2)友元函数不能用const修饰
(3)友元函数可以在类定义的任何地方声明,不受类访问限定符限制
(4)一个函数可以是多个类的友元函数
(5)友元函数的调用和普通函数的调用和原理相同
输入输出运算符的重载的友元函数
class Date
{
friend ostream & operator << (ostream& os, const Date & d);
friend istream & operator >> (istream& is, Date & d);
private:
int _year;
int _month;
int _day;
};
ostream & operator << (ostream& os, const Date & d)
{
os << d._year << endl;
os << d._month << endl;
os << d._day << endl;
return os;
}
istream & operator >> (istream& is, Date & d)
{
cout << "请输入年-月-日:" << endl;
is >> d._year;
is >> d._month;
is >> d._day;
return is;
}
void test()
{
Date d;
cin >> d;
cout << d;
}
二、友元类
整个类可以是另一个类的友元。友元类中的每一个成员函数都是另一个类的友元函数,都可访问另一个中保护或私有数据成员
class Time
{
//Date是Time的友元
friend class Date;
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
void Show()
{
cout << _year << "-" << _month << "-" << _day << endl;
//定义为友元类后,可以访问Time类对象的所有成员
cout << _t._hour << "-" << _t._minute << "-" << _t._second << endl;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
友元的优点:提高了程序运行效率
友元的缺点:破坏了类的封装性和隐藏性
注意:
友元关系不能继承
友元关系是单向的,不具有交换性
友元关系不能传递
面试题
重载成员函数,为什么不重载称全局?
答:全局的不好访问私有的
三、静态成员
1、类里面static修饰成员,称为静态类成员
2、类的静态成员是该类型的所有对象对象所共享
class Date
{
public:
Date()
{
cout << "Date()" << endl;
++count;
}
void Show()
{
cout << "year" << _year << endl;
cout << "month" << _month << endl;
cout << "day" << _day << endl;
}
//静态成员函数
static void printcount()
{
cout << "count" << count << endl;
}
private:
int _year;
int _month;
int _day;
private:
static int count;//静态成员变量,统计创建时间个数
};
int Date::count = 0;//定义并初始化静态成员变量
void test()
{
Date d1, d2;
//访问静态成员
Date::printcount();
}
注意:
静态成员函数没有隐含的this指针参数,所以可以使用类型::作用域访问符直接调用静态成员函数。
面试题
1、静态成员函数可以调用非静态成员函数或非静态成员变量吗?
答:不可以,因为静态成员函数没有this指针
2、非静态成员函数可以调用类的静态成员函数吗?
答:可以