C++学习笔记30:友元类、内部类和封装

发布时间:2026/5/28 20:23:12

C++学习笔记30:友元类、内部类和封装 目录一、友元类是什么二、友元类的简单例子三、友元类的特点1. 友元关系是单向的2. 友元关系不能传递四、什么是内部类五、内部类的特点六、封装是什么七、为什么要封装八、友元和封装的关系九、小结一、友元类是什么前面学习了友元函数friend void PrintDate(const Date d);友元函数可以让一个普通函数访问类的私有成员。而友元类是让一个类可以访问另一个类的私有成员。写法是friend class 类名;例如class Date { friend class Time; private: int _year; int _month; int _day; };这表示Time 类是 Date 类的友元类Time 类中的成员函数可以访问 Date 类中的私有成员。二、友元类的简单例子#include iostream using namespace std; class Date { friend class Time; public: Date(int year 2024, int month 1, int day 1) : _year(year) , _month(month) , _day(day) {} private: int _year; int _month; int _day; }; class Time { public: void PrintDate(const Date d) { cout d._year - d._month - d._day endl; } }; int main() { Date d(2024, 5, 1); Time t; t.PrintDate(d); return 0; }运行结果2024-5-1这个例子中_year、_month、_day 都是 Date 的私有成员。正常情况下time 类是不能直接访问它们的。但是因为 Date 中声明了friend class Time;所以 Time 类就可以访问 Date 的私有成员。三、友元类的特点友元类有以下几个特点1. 友元类可以访问另一个类的滴油成员 2. 友元关系是单向的 3. 友元关系不能传递 4. 友元会破坏封装不能滥用。1. 友元关系是单向的如果写class Date { friend class Time; };表示 Time 类可以访问 Date 的私有成员。但是不代表 Date 类可以访问 Time 的私有成员。如果要 Date 访问 Time 类的私有成员需要在 Time 类中声明class Time { friend class Date; };2. 友元关系不能传递如果A 是 B 的友元 B 是 C 的友元不能推出A 是 C 的友元友元关系只能对当前声明的类有效。四、什么是内部类内部类就是在一个类的内部再定义一个类。例如class A { public: class B { public: void Print() { cout B class endl; } }; };这里 B 就是 A 的内部类。使用内部类时需要通过类域访问A::B b; b.Print();完整代码#include iostream using namespace std; class A { public: class B { public: void Print() { cout B class endl; } }; }; int main() { A::B b; b.Print(); return 0; }运行结果B class五、内部类的特点内部类有以下几个特点1. 内部类定义在另一个类的内部 2. 使用是要通过 外部类::内部类 的方式 3. 内部类受外部类的类域限制 4. 内部类天然具有外部类的友元权限也就是说内部类可以访问外部类的私有成员。例如#include iostream using namespace std; class A { public: class B { public: void Print(const A a) { cout a._a endl; } }; private: int _a 10; }; int main() { A a; A::B b; b.Print(a); return 0; }运行结果10这里 _a 是 A 的私有成员但是内部类 B 可以访问它。不过内部类在 C 中用的没有 Java 那么多基本了解即可。六、封装是什么封装是面向对象的三大特性之一。简单说就封装就是把数据和操作数据的方法放到一起并通过访问限定符控制外部能不能直接访问。例如class Date { public: void Print() { cout _year - _month - _day endl; } private: int _year; int _month; int _day; };这里 _year、_month、_day 是私有成员外部不能直接访问。外部想使用日期只能通过公有接口比如Print();这就是封装。七、为什么要封装封装的意义主要有两个1. 保护数据 2. 降低代码之间的耦合如果成员变量全部写成 public外部可以随意修改d._month 100; d._day -1;这样对象很容易进入错误状态。如果把数据放到 private再通过成员函数控制访问就可以在函数中加入检查逻辑。例如void SetDate(int year, int month, int day) { if (month 1 month 12) { _month month; } }这样可以减少错误。八、友元和封装的关系友元可以让类外的函数或其它类访问私有成员。这确实很方便但是会破坏封装性。所以友元要谨慎使用。一般原则是能用成员函数解决就优先用成员函数 确实不适合写成成员函数时再考虑友元比如输入输出运算符重载cout d; cin d;这种场景下为了保证正常输入习惯operator 和 operator 通常携程全局函数然后声明为友元。这属于比较合理的友元使用场景。九、小结本篇主要学习了友元类、内部类和封装。需要记住友元类使用 friend class 类名; 声明友元类可以访问另一个类的私有成员友元关系是单向的友元关系不能传递的内部类在是一个类的内部定义的类内部类使用时需要写成 外部类::内部类 内部类天然具有外部类的友元权限封装是把数据和操作数据的方法放在一起封装可以保护数据降低耦合友元会破坏封装所以不能滥用。友元和内部类本质上都是C中突破访问限制的机制。学到他们不是为了经常使用而是为了理解C类和对象访问权限、类域以及封装之间的关系。

相关新闻