• C++基础——友元函数和内部类讲解


          目录    

    一.友元:

            友元函数:

    友元类

    二.内部类

    1.定义:

    2.内部类的另一个特点:


    一.友元:

            友元函数

            友元为类外的函数提供了一种突破封装的方式,简单来说就是让类外能够破解private、protected型私有类型成员变量或函数,为其提供了便利。之前在讲流提取、流插入运算符函数重载的时候简单介绍了一下友元,大家可以来看一看这篇博客中,类外是如何能够调用重载函数的。C++基础——流插入提取运算符重载函数_

    1. class Date
    2. {
    3. public:
    4. Date(int year = 1900, int month = 1, int day = 1)
    5. : _year(year)
    6. , _month(month)
    7. , _day(day)
    8. {}
    9. private:
    10. int _year;
    11. int _month;
    12. int _day;
    13. };
    14. ostream& operator<<(ostream& _cout, const Date& d)
    15. {
    16. _cout << d._year << "-" << d._month << "-" << d._day;
    17. return _cout;
    18. }
    19. istream& operator>>(istream& _cin, Date& d)
    20. {
    21. _cin >> d._year;
    22. _cin >> d._month;
    23. _cin >> d._day;
    24. return _cin;
    25. }
    26. int main()
    27. {
    28. Date d;
    29. cin >> d;
    30. cout << d << endl;
    31. return 0;
    32. }

            流插入和流提取运算符想要在类外进行运算符的重载,需要用到友元,让这两个函数在类内发布友元声明,这样类外就可以将其视为朋友,轻而易举的访问到Date类的非公有成员了。

    友元类

            假设类A想要访问类B的非公有成员,就需要在类B中存放类A的友元声明了,也是friend关键字+class+类名即可。

            

    1. class Time{
    2. friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类
    3. //中的私有成员变量
    4. public:
    5. Time(int hour = 0, int minute = 0, int second = 0)
    6. : _hour(hour)
    7. , _minute(minute)
    8. , _second(second)
    9. {}
    10. private:
    11. int _hour;
    12. int _minute;
    13. int _second;
    14. };
    15. class Date{
    16. public:
    17. Date(int year = 1900, int month = 1, int day = 1)
    18. : _year(year)
    19. , _month(month)
    20. , _day(day)
    21. {}
    22. void SetTimeOfDate(int hour, int minute, int second){
    23. // 直接访问时间类私有的成员变量
    24. _t._hour = hour;
    25. _t._minute = minute;
    26. _t._second = second;
    27. }
    28. private:
    29. int _year;
    30. int _month;
    31. int _day;
    32. Time _t;
    33. };

    将Time类外的Date类在Time类内加上friend, Time类会视Date类为朋友,Date类可以访问Time类的私有成员,Date可以偷Time的家,而Time类不是Date的朋友,Time类不可以访问Date的私有成员。而在SetTimeOfDate函数中,成员变量_t就可以直接访问到Time类的非公有成员。 

            

            需要注意的是:使用友元会增加耦合度,破坏了封装,所以友元不宜多用。

     

    二.内部类

    1.定义:

            将一个类定义在另一个类的内部,内部类是一个独立的类,它不属于外部类,更不能通过外部类去访问内部类成员。

    示例代码,如下:

    1. class A
    2. {
    3. private:
    4. static int k;
    5. int h;
    6. public:
    7. class B // B天生就是A的友元,类B可以访问类A的成员,但类A不能访问类B的成员
    8. {
    9. public:
    10. void foo(const A& a)
    11. {
    12. cout << k << endl; //OK
    13. cout << a.h << endl;//OK
    14. }
    15. private:
    16. double _b;
    17. int _a;
    18. };
    19. };
    20. int A::k = 1;
    21. int main()
    22. {
    23. A aa;
    24. cout << sizeof(A) << endl;
    25. cout << sizeof(aa) << endl;
    26. cout << sizeof(A::B) << endl; //16字节
    27. A::B b;
    28. b.foo(A());
    29. return 0;
    30. }

            由定义得,内部类不属于外部类,所以我写了两行行检测类A,类A对象存储大小的代码,发现:

            结果都为4字节,即只存储了int h的大小,且静态成员变量在静态区,所以不进内存空间,那么类B中的a,b成员完全没有算进去。所以由此推断:这个内部类等价于是两个独立的类 。

            但是若类B想要创建对象还是得通过类A才可以,毕竟类B在类A的内部        ~哈哈哈,没办法!

    2.内部类的另一个特点:

            内部类天生就是是外部类的友元,也就是说,不需要在类A中发表类B的友元声明,类B也可以随意的访问类A的非公有成员!!!

             

     

     

     

     

  • 相关阅读:
    服务器安装运行jupyter notebook
    Spring Boot 中如何解决跨域问题、Spring Cloud 5大组件、微服务的优缺点是什么?
    获取 Android 手机屏幕的实际大小(英寸)
    Docker 之 基础篇(安装、卸载、阿里云镜像加速、常用命令、发布、应用安装)
    linux shell awk sed 使用
    什么是Redis?
    PCL 使用克拉默法则进行三点定圆(二维)
    安全漏洞-linux漏洞修复命令
    window安装HBase(单机版)
    微信小程序获取用户信息
  • 原文地址:https://blog.csdn.net/weixin_69283129/article/details/127820724