【C++】类和对象的知识点--2 https://developer.aliyun.com/article/1424623?spm=a2c6h.13148508.setting.25.214f4f0eqBSn46
三,友元
在C++中,友元是一个关键字,它用于允许一个类的成员函数访问另一个类的私有和保护成员。使用友元函数或友元类,可以访问一个类的私有和保护成员以及类中的成员函数,就像它们是公共成员一样,可以不受权限的限制进行任意访问。其中友元共分为:友元函数和友元类。
3-1,友元函数
友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。
class Date { //友元函数的声明 friend ostream& operator<<(ostream& _cout, const Date& d); friend istream& operator>>(istream& _cin, Date& d); public: Date(int year = 2023, int month = 10, int day = 16) : _year(year) , _month(month) , _day(day) { } private: int _year; int _month; int _day; }; //友元函数的定义 ostream& operator<<(ostream& _cout, const Date& d) { _cout << d._year << "-" << d._month << "-" << d._day;//访问类中的私有成员变量 return _cout; } istream& operator>>(istream& _cin, Date& d) { _cin >> d._year >> d._month >> d._day;//访问类中的私有成员变量 return _cin; }
这里要说明以下几点:
1,友元函数可访问类的私有和保护成员,但不是类的成员函数。
2,友元函数不能用const修饰。
3,友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
3-2,友元类
在C++中,友元类是一种特殊的关系,它允许一个类访问另一个类的私有和保护成员。使用友元类,可以访问一个类的私有和保护成员,就像它们是公共成员一样。
要声明一个类为另一个类的友元类,可以在类定义中加入friend关键字,并使用类名作为友元类的声明。
class Time { // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量 friend class Date; int _hour; int _minute; int _second; }; class Date { public: void SetTimeOfDate(int hour, int minute, int second) { // 直接访问时间类私有的成员变量 _t._hour = hour; _t._minute = minute; _t._second = second; } private: int _year; int _month; int _day; Time _t; };
四,内部类
概念:
如果一个类定义在另一个类的内部,那么这个定义在内部的类就叫做内部类。内部类是一个独立的类, 它不属于外部类,更不能通过外部类的对象去访问内部类的成员,即外部类不是内部类的友元,但内部类是外部类的友元类,即内部类可以通过外部类的对象参数来访问外部类中的所有成员。
注意:
1,内部类可以直接访问外部类中的静态成员,不需要外部类的对象/类名。
2,定义内部类时不能直接定义,需要外部类来限定域的作用空间。
#include <iostream> using namespace std; class A { private: static int k; int h; public: class B // B天生就是A的友元 { public: void fun(const A& a) { //这里要说明的是内部类可以直接访问外部类中的静态成员,不需要外部类的对象/类名 cout << k << endl;//直接访问静态成员 cout << a.h << endl;//访问A类中的私有成员 } }; }; int A::k = 1; int main() { A::B b;//定义内部类对象b return 0; }
五,匿名对象
概念:在类中,我们可以对类进行不取名字的方式定义,这种定义对象的方式叫做匿名对象。其中,匿名对象的生命周期只有这一行,当这一行结束时将会自动调用析构函数。
匿名对象在只需使用一次的场合下非常好用,这里我们先了解一下,后面的文章将会深入展开这一方面。使用如下:
#include <iostream> using namespace std; class A { public: A(int a = 0) :_a(a) { } ~A() { cout << "~A()" << endl; } int GetData() { return _a; } private: int _a; };; int main() { A();//建立匿名对象,这一行结束后将调用析构函数 A().GetData();//使用匿名对象调用成员函数,结束后将自动调用析构函数 return 0; }
总:本章节只是初步学习类与对象中的知识点,具体的深入探索到了后面会详细讲解,这里我们只需先理解并会用即可。