【C++】类和对象(五)友元、内部类、匿名对象

简介: 【C++】类和对象(五)友元、内部类、匿名对象

前言:前面我们说到类和对象是一个十分漫长的荆棘地,今天我们将走到终点,也就是说我们对于C++算是正式的入门了。

d6dc0126edd141a985d72de501ef756b.jpg


类和对象

友元

友元是 C++ 中的一个特殊声明,允许一个类或函数访问另一个类的私有成员或受保护成员。友元的声明可以在类中出现,也可以在类外出现。

  • 友元关系是单向的,不具有交换性。
  • 友元关系不能传递如果C是B的友元, B是A的友元,则不能说明C时A的友元。
  • 友元关系不能继承,在继承位置再给大家详细介绍。

友元函数: 友元函数是在类外部声明的函数,它可以直接访问类的私有成员或受保护成员。在类中声明一个函数为友元函数,需要使用 friend 关键字。

友元类: 友元类是在一个类中声明的另一个类,被声明为友元类的类可以访问该类的私有成员或受保护成员。在类中声明一个类为友元类,需要使用 friend 关键字

class A {
private:
    int x;
public:
    friend class B; // 声明类 B 是类 A 的友元
    friend void func(); // 声明函数 func 是类 A 的友元
    A(int n = 10)
    {
        x = n;
    }
};

class B {
public:
    void printA(A obj) {
        cout <<"友元类访问私有成员:" << obj.x << endl; // 类 B 可以访问类 A 的私有成员 x
    }
};

void func() {
    A obj(1);
    cout <<"func函数访问的私有成员: " << obj.x << endl; // 函数 func 可以访问类 A 的私有成员 x
}

int main()
{
    A obj(5);
    func();//友元函数可以访问类中的私有成员
    B obj1;
    obj1.printA(obj);//类 B 可以访问类 A 的私有成员 x
    return 0;
}

友元关系是单向的,即如果类 A 是类 B 的友元,不代表类 B 是类 A 的友元,需要分别进行声明。

注意,过度使用友元会破坏封装性,并增加代码的复杂性和耦合性,因此在使用友元时应慎重考虑。


内部类

概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

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

通过外部类使用内部类

在下面的示例中,Inner是一个内部类,Outer是一个外部类.

实例演示:

class Outer
{
public :
  Outer(int s = 1, int q = 1)
    :m(s)
    ,n(q)
  {
  }
  void Print()
  {
    cout << "你好我是外部类 : " << m << " " << n << endl;

  }
  class Inner
  {
  public:
    Inner(int n = 1, int m = 1)
      :x(n)
      ,y(m)
    {
    }
    void Print()
    {
      cout << "你好我是内部类 : " << x << " " << y << endl;
    }
  private :
    int x;
    int y;
  };
private :
  int m;
  int n;
};

int main()
{
  Outer outobj(9, 22);
  Outer::Inner inobj(10,20);//外部使用内部类
  inobj.Print();
  outobj.Print();
  return 0;
}


内部类是外部类的友元

实例演示:

外部类无法直接访问内部类的成员

实例演示:


总结:

C++中的内部类指的是在一个类的内部定义的类。内部类具有以下特点:

  1. 内部类是一个嵌套在外部类中的类,它们之间可以互相访问彼此的成员。
  2. 内部类可以访问外部类的所有成员,包括私有成员。
  3. 内部类的对象可以在外部类的成员函数中直接创建。
  4. 内部类的作用域被限定在外部类中,外部类的成员函数可以访问内部类,但外部类的对象不能直接访问内部类。
  5. 内部类可以使用外部类的成员作为自己的成员,从而实现更灵活的设计和封装。
  6. 内部类可以被声明为私有,这样只有外部类的成员函数可以访问它。
  7. 内部类的声明可以在外部类的定义之外,但定义必须在外部类的定义之内。
  8. . sizeof(外部类)=外部类,和内部类没有任何关系。

匿名对象

C++中的匿名对象是指没有被命名的对象,它们在创建后可以直接使用,但无法通过变量名来引用。匿名对象通常用于简单的一次性操作或者作为函数的参数。

匿名对象的特点如下:

  1. 匿名对象在创建后立即执行相关操作,并在表达式结束后被销毁。
  2. 匿名对象无法被引用,因此无法在其他地方被使用。
  3. 匿名对象适用于一些临时的、不需要保留状态的操作,如简单的计算或调用函数。
    实例演示1:
class Myclass
{
public:
    Myclass(int year = 2024, int month = 1, int day = 1)
        :_year(year)
        ,_month(month)
        ,_day(day)
    {
    }
    void Print()
    {
        cout << "year: " << _year << " month: " << _month << " day: " << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Myclass(2024, 2, 16).Print();//调用匿名对象
    Myclass A = 2023;//这里会产生隐式转换
    A.Print();
    Myclass B;调用一次构造函数
    B.Print();
    B = Myclass(2003, 9, 22);//此处等价于赋值,且这个匿名对象会调用一次给构造函数
    B.Print();
  return 0;
}


匿名对象在以下情况下会调用拷贝构造、默认构造和析构函数:

如果生成的匿名对象在外部有对象等待被其实例化,此匿名对象的生命周期就变成了外部对象的生命周期;如果生成的匿名对象在外面没有对象等待被其实例化,此匿名对象将会生成之后,立马被析构。

好啦,今天的内容就到这里啦,下期内容预告类和对象(五)友元、内部类、匿名对象等,下期就会对类和对象进行最后的收尾了,各位加油呐!

好啦,今天的内容就到这里啦,下期内容预告C/C++内存管理,类和对象就在这里和大家告一段落了,各位加油呐!


结语:今天的内容就到这里吧,谢谢各位的观看,如果有讲的不好的地方也请各位多多指出,作者每一条评论都会读的,谢谢各位。


相关文章
|
自然语言处理 安全 C++
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
11429 4
|
1月前
|
缓存 测试技术 API
Qwen3.8-Flash 来了,Qwen3.8-Flash 功能详解,100万上下文、Agent、Coding 都加强了!
在大模型工程落地的真实场景当中,开发者长期面临一组难以平衡的矛盾:旗舰版本模型推理效果强,但是Token成本高,高并发业务大规模调用时开销压力巨大;轻量化模型成本低廉,但是上下文窗口有限,代码仓库读取、超长文档分析、长链路Agent任务很容易出现信息遗忘,工具调用、代码生成的稳定性不足。很多项目只能被迫采用混合策略,长文档先做文本切片拆分,再交给小模型处理,切片过程会丢失上下文关联信息,增加大量预处理开发工作量。
709 0
|
11月前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
1967 292
|
4月前
|
存储 编解码 运维
2026年阿里云轻量应用服务器配置价格表与性能测评
阿里云轻量应用服务器是面向入门级用户、个人开发者及小微企业的一站式云服务产品,主打**开箱即用、极简运维、高性价比**,整合计算、存储、网络资源于一体,无需复杂配置即可快速部署应用。2026年产品全面升级,所有规格默认配备**200M峰值带宽+不限流量**,彻底告别流量焦虑,同时提供丰富的应用镜像与简化控制台,大幅降低云计算使用门槛。
1366 0
|
5月前
|
前端开发 API 内存技术
对比claude code等编程cli工具与deepseek v4的适配情况
DeepSeek V4发布后,多家编程工具因未适配其强制要求的`reasoning_content`字段而报错。本文对比Claude Code、GitHub Copilot、Langcli、OpenCode及DeepSeek-TUI等主流工具的兼容性:Claude Code需按官方方式配置;Langcli表现最佳,开箱即用且无报错;Copilot与OpenCode暂未修复问题;DeepSeek-TUI尚处早期阶段。
4493 3
对比claude code等编程cli工具与deepseek v4的适配情况
|
JSON Dart Android开发
Flutter 2024: Impeller引擎引领渲染新纪元
Flutter 2024以Impeller引擎引领渲染新时代,全面提升性能与流畅度。Impeller已在iOS及Android(支持Vulkan/OpenGL)全面部署,Material 3集成深化视觉体验,多视图支持增强复杂UI管理。Dart 3.2与3.4版本迭代优化语言特性与性能,引入宏编程简化JSON处理。桌面与Web端持续优化,深化平台适配。
969 14
|
10月前
|
网络协议 应用服务中间件 网络安全
阿里云SSL证书阿里云HTTPS证书全流程实战指南:购买、创建、申请与部署深度解析
本文详细介绍阿里云SSL证书的选型、购买、申请、部署及运维全流程,涵盖DV/OV/EV证书区别、DNS/文件/邮件验证方式、Nginx/Apache/CDN部署实操,并提供续费、吊销、托管等管理策略,助力网站快速实现HTTPS安全加密。
阿里云SSL证书阿里云HTTPS证书全流程实战指南:购买、创建、申请与部署深度解析
|
9月前
|
存储 人工智能 数据处理
2026年阿里云对象存储OSS最新收费标准价格表:
阿里云OSS按存储、流量、请求等维度收费,核心模式为按量付费与资源包(包年包月),未用功能不计费。主要费用为存储费(标准/低频/归档等类型)和流量费(仅公网流出,分闲忙时计费),另有请求、数据处理等增值费用。开通、上传及内网流量免费,新用户享免费额度,官网提供精准报价。
|
存储 弹性计算 数据管理
阿里云对象存储OSS收费标准:存储费、流量价格及不同计费模式全解析
阿里云OSS收费标准涵盖存储、流量等费用,支持按量付费与资源包两种模式。标准存储按量0.09元/GB/月,包年500GB仅需118.99元,流量费按公网出方向计费,闲时0.25元/GB,忙时0.5元/GB,可购流量包更优惠。
3309 7
|
开发框架 前端开发 开发者
【Flutter前端技术开发专栏】Flutter的Material Design与Cupertino Design风格
【4月更文挑战第30天】Flutter框架支持Material Design和Cupertino Design两种设计风格,助力开发者创建吸引人的移动应用。Material Design基于现实世界物理规律,提供`Scaffold`、`Card`等组件,实现纸片效果和直观体验。Cupertino Design注重简洁图标和流畅动画,借助`CupertinoTabScaffold`、`CupertinoActivityIndicator`等组件呈现苹果风格界面。Flutter的`Theme`类允许统一管理应用样式,开发者可根据需求混搭两种风格,实现跨平台的优质用户体验。
1227 0
【Flutter前端技术开发专栏】Flutter的Material Design与Cupertino Design风格