服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++超详细讲解友元与内部类

C++超详细讲解友元与内部类

2023-02-08 14:58beyond.myself C/C++

朋友们好,这篇播客我们继续C++的初阶学习,现在对我们对C++的友元,内部类知识点做出总结,整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步

一.友元

友元分为: 友元函数 和 友元类

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

1.友元函数

(1)引入原因

operator<<:因为cout 的 输出流对象和隐含的 this 指针在抢占第一个参数的位置 。 this 指针默认是第一个参数也就是左操数了。但是实际使用中cout 需要是第一个形参对象,才能正常使用。所以我们要将 operator<< 重载成全局函数。但是这样的话,又会导致类外没办法访问成员,那么这里就需要友元来解决。operator>> 同理。

(2)友元函数作用

友元函数 可以 直接访问 类的 私有 成员,它是 定义在类外部 的 普通函数 ,不属于任何类,但需要在类的内部声明,声明时需要加friend 关键字。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
using namespace std;
class Date
{
    // 友元函数
    friend ostream& operator<<(ostream& out, const Date& d);
public:
private:
    int _year;
    int _month;
    int _day;
};
ostream& operator<<(ostream& out, const Date& d)
{
    out << d._year << "/" << d._month << "/" << d._day << endl;
    return out;
}
int main()
{
    Date d;
    //d << cout;
    cout << d;
    return 0;
}

(3)友元函数特征

【1】友元函数 可访问类的私有和保护成员,但 不是类的成员函数

【2】友元函数 不能用 const 修饰(因为没有this指针)

【3】友元函数 可以在类定义的任何地方声明, 不受类访问限定符限制,放在public,private中都行,不放这两个里面放在最前面也行,一般都是定义最前面的

【4】一个函数可以是多个类的友元函数

【5】友元函数的调用与普通函数的调用和原理相同

2.友元类

(1)解释

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Date; // 前置声明:因为编译器是向上查找,在Time类中
class Time
{
    //友元类
    friend class Date;
声明日期类为时间类的友元类,则在日期类中就可以直接访问Time类中的私有成员变量
public:
    Time(int hour=0, int minute=0, int second = 0)
        : _hour(hour)
        , _minute(minute)
        , _second(second)
    {}
private:
    int _hour;
    int _minute;
    int _second;
};
class Date
{
public:
    Date(int year = 1900, int month = 1, int day = 1)
        : _year(year)
        , _month(month)
        , _day(day)
    {}
    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;
};

在Date类中有一自定义成员变量Time _t;,成员函数 SetTimeOfDate 想访问 _t 对象的成员变量,因为类Time中的成员变量是私有的,所以正常情况无法访问,则需要借助友元类:

想在Date类中访问Time类对象的私有成员变量,就需要在类Time中声明日期类为时间类的友元类,则在日期类中就可以直接访问Time类中的私有成员变量。

格式:friend class Date;

(在Date类中访问Time类对象的成员变量:在Time类中写日期类声明并在前面加friend)

(2)友元类特征

【1】友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

【2】友元关系是单向的,不具有交换性。 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

【3】友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。

二.内部类(不常用)

1.概念

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。

注意:此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。

注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

2.特性 

1. 内部类可以定义在外部类的 public 、 protected 、 private 都是可以的。

2. 注意内部类可以直接访问外部类中的 static 、枚举成员,不需要外部类的对象 / 类名。

3. sizeof( 外部类 )= 外部类,和内部类没有任何关系

举例:B是A的内部类,B是A的友元,A不是B的友元,A的大小是4字节,类A的大小不包含静态变量k(存在静态区)和成员函数(存在公共代码段)和内部类B,类A的大小仅仅只有h,所以是4字节。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A {
private:
    static int k;
    int h;
public:
    class B    //内部类
    {
    public:
        void foo(const A& a)
        {
            cout << k << endl;    //B可以直接访问A内部成员变量
            cout << a.h << endl;    //B可以直接访问A内部成员变量
        }
    };
};
int main()
{
    cout << sizeof(A) << endl;
    A aa;
    A::B bb;    //定义B的对象时,需要指定是A的类域 A::
    return 0;
}

到此这篇关于C++超详细讲解友元与内部类的文章就介绍到这了,更多相关C++友元与内部类内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/zhang_si_hang/article/details/125173637

延伸 · 阅读

精彩推荐
  • C/C++C++设计模式中的桥模式你了解吗

    C++设计模式中的桥模式你了解吗

    这篇文章主要为大家详细介绍了C++设计模式中的桥模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够...

    吃米饭4202022-10-25
  • C/C++C++结构体字节对齐示例

    C++结构体字节对齐示例

    这篇文章主要为大家介绍了C++结构体字节对齐示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    Bug挖掘机8452023-02-08
  • C/C++C++编程使用findfirst和findnext查找及遍历文件实现示例

    C++编程使用findfirst和findnext查找及遍历文件实现示例

    这篇文章主要为大家介绍了C++编程如何使用findfirst和findnext查找及遍历文件实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助...

    ranjiewen10502022-01-24
  • C/C++全面解析C++中的析构函数

    全面解析C++中的析构函数

    这篇文章主要介绍了C++中的析构函数,为C++入门学习中的基础知识,需要的朋友可以参考下...

    C++教程网8192021-03-23
  • C/C++C++结构体数组实现贪吃蛇

    C++结构体数组实现贪吃蛇

    这篇文章主要为大家详细介绍了C++结构体数组实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    oyxy20198552021-08-23
  • C/C++C++选择文件夹代码的封装

    C++选择文件夹代码的封装

    这篇文章主要介绍了C++选择文件夹代码的封装,实例展示了将选择文件夹功能代码封装为一个类并对其进行实例化调用的过程,对于学习C++程序设计有不错的...

    C++教程网10712021-02-06
  • C/C++详谈C++的内存泄漏问题

    详谈C++的内存泄漏问题

    下面小编就为大家带来一篇详谈C++的内存泄漏问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    jingxian7182021-05-11
  • C/C++C语言简明讲解归并排序的应用

    C语言简明讲解归并排序的应用

    这篇文章主要介绍了 c语言排序之归并排序,归并就是把两个或多个序列合并,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借...

    Mi ronin8592022-12-07