C++学习笔记——友元、嵌套类、异常

news2024/9/20 22:50:37

目录

一、友元

一个使用友元的示例代码

输出结果

二、嵌套类

一个使用嵌套类的示例代码

输出结果

三、异常

一个使用异常处理的示例代码

输出结果

四、结论

五、使用它们的注意事项


上一篇文章链接:

C++中的继承和模板是非常强大和灵活的特性,它们可以帮助我们实现代码复用、抽象和泛化等目标。本文将着重介绍私有继承、多重继承和类模板这三个C++中比较重要的特性。

C++学习笔记——私有继承、多重继承、类模板-CSDN博客例如,我们可以使用模板参数来定义成员变量和成员函数,或者使用特化(partial specialization)和偏特化(full specialization)来针对不同的情况实现不同的行为。私有继承是一种比较特殊的继承方式,它在语法上与公有继承和保护继承没有太大区别,但是其继承关系所暴露的接口和成员变量都会被隐藏起来,只有派生类自己可以访问到基类的成员。此外,多重继承也可以用来实现接口继承和实现继承的分离,从而更好地实现面向对象的编程思想。是一个类模板,可以使用不同类型的数据来实例化。https://blog.csdn.net/m0_62338174/article/details/135573044?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135573044%22%2C%22source%22%3A%22m0_62338174%22%7D 

C++ 是一门功能强大的编程语言,它提供了很多工具来实现各种编程任务。在本文中,我们将介绍 C++ 中的三个重要概念:友元、嵌套类和异常。

一、友元

C++ 中的友元是一种机制,允许一个类或函数访问另一个类的私有成员。当一个类或者函数被声明为另一个类的友元后,它就可以在访问该类的私有成员时绕过访问权限检查,直接访问该类的私有成员。

友元可以是一个类、一个函数或者一个整个命名空间。为了使一个类成为另一个类的友元,需要在其中一个类的声明中使用 friend 关键字来声明该类是另一个类的友元。需要注意的是,友元关系是单向的,即如果 A 类是 B 类的友元,那么 B 类并不一定是 A 类的友元。

使用友元的优点在于它可以提高程序的灵活性和可读性。比如,一个类中的某些私有成员可能只是为了方便内部实现而设置的,但是这些成员对于外部用户来说并没有意义,此时可以通过把需要访问这些私有成员的类或函数声明为友元来提高程序的可用性和可读性。

然而,需要注意的是,过度使用友元会破坏封装性,并降低代码的可维护性。因此,在使用友元时,应该谨慎使用,只在必要的情况下使用友元。

一个使用友元的示例代码

#include <iostream>

class A {
private:
    int x;

public:
    A(int value) : x(value) {}

    friend class B;
};

class B {
public:
    void showMessage(A& a) {
        std::cout << "x = " << a.x << std::endl;
    }
};

int main() {
    A a(10);
    B b;
    b.showMessage(a);
    return 0;
}

在这个示例中,B 类被声明为 A 类的友元,因此 B 类可以访问 A 类的私有成员 xshowMessage() 函数通过引用参数来接收 A 类的对象,并输出了它的私有成员 x 的值。

输出结果

x = 10

友元的使用可以提高程序的灵活性和可读性。但是,需要注意的是过度使用友元会破坏封装性,并降低代码的可维护性。

二、嵌套类

C++ 中的嵌套类是指一个类定义在另一个类的内部,它可以访问外部类的私有成员和保护成员,但外部类不能访问嵌套类的私有成员。嵌套类可以看作是一种逻辑上的组织方式,它可以将与主类相关的功能归纳在一起,提高程序的封装性和可读性。

使用嵌套类的优点在于它可以提高程序的封装性和可读性。比如,一个类中可能包含多个不同的子类,如果将这些子类定义在主类的内部,可以使程序更加整洁和易读。

然而,需要注意的是,过度使用嵌套类会增加代码的复杂度,并降低代码的可维护性。因此,在使用嵌套类时,应该谨慎使用,只在必要的情况下使用嵌套类。

一个使用嵌套类的示例代码

#include <iostream>

class A {
private:
    int x;

public:
    A(int value) : x(value) {}

    class B {
    public:
        void showMessage(A& a) {
            std::cout << "x = " << a.x << std::endl;
        }
    };
};

int main() {
    A a(10);
    A::B b;
    b.showMessage(a);
    return 0;
}

在这个示例中,B 类被嵌套在 A 类的内部,因此 B 类可以访问 A 类的私有成员 xshowMessage() 函数通过引用参数来接收 A 类的对象,并输出了它的私有成员 x 的值。

输出结果

x = 10

嵌套类的使用可以提高程序的封装性和可读性。但是,需要注意的是过度使用嵌套类会增加代码的复杂度,并降低代码的可维护性。

三、异常

C++ 中的异常是指程序运行过程中遇到的错误或异常情况。当程序出现异常时,程序会跳转到异常处理器,并执行一些特定的代码,以处理异常并恢复程序的正常运行。C++ 中的异常处理机制允许程序员在程序出现错误时选择不同的处理方式,从而提高程序的可靠性和鲁棒性。

异常可以分为两类:标准异常和自定义异常。标准异常是 C++ 内置的异常类型,它们定义在 <stdexcept> 头文件中,包括 std::invalid_argumentstd::range_errorstd::logic_error 等。自定义异常是程序员自己定义的异常类型,可以通过继承 std::exception 类来实现。

使用异常处理的优点在于它可以提高程序的健壮性和可读性。当程序出现异常时,程序会跳转到异常处理器,并执行一些特定的代码,以处理异常并恢复程序的正常运行。

然而,需要注意的是,过度使用异常处理会影响程序的性能,并增加代码的复杂度。因此,在使用异常处理时,应该谨慎使用,只在必要的情况下使用异常处理。

一个使用异常处理的示例代码

#include <iostream>
#include <stdexcept>

int divide(int x, int y) {
    if (y == 0) {
        throw std::invalid_argument("Divide by zero.");
    }
    return x / y;
}

int main() {
    int x = 10, y = 0;
    try {
        int z = divide(x, y);
        std::cout << "z = " << z << std::endl;
    } catch (std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

在这个示例中,divide() 函数用于计算两个整数的商,如果除数为零,则抛出一个 std::invalid_argument 异常。在 main() 函数中,我们使用 try-catch 块来捕获可能抛出的异常,当程序运行到抛出异常的地方时,程序会跳转到 catch 块并执行其中的代码。

输出结果

Error: Divide by zero.

异常处理的使用可以提高程序的健壮性和可读性。但是,需要注意的是过度使用异常处理会影响程序的性能,并增加代码的复杂度。

四、结论

友元、嵌套类和异常是 C++ 中三个重要的概念,它们可以提高程序的灵活性、封装性和健壮性。但是,需要注意的是过度使用它们会破坏程序的封装性、增加代码的复杂度和影响程序的性能。因此,在编写程序时,应根据实际情况选择适当的编程技术来提高程序的可读性、可维护性和可靠性。

五、使用它们的注意事项

在使用友元、嵌套类和异常时,需要注意以下事项:

  1. 友元关系是单向的,如果将一个类 A 定义为另一个类 B 的友元,则 B 不一定是 A 的友元。
  2. 友元可以提高程序的灵活性和可读性,但过度使用会破坏封装性,降低代码的可维护性。
  3. 嵌套类可以将与主类相关的功能归纳在一起,提高程序的封装性和可读性,但过度使用会增加代码的复杂度,降低代码的可维护性。
  4. 异常处理机制可以提高程序的健壮性和可读性,但过度使用会影响程序的性能,增加代码的复杂度。在编写程序时,应该根据实际情况选择适当的处理方式。
  5. 在使用异常处理时,应该明确什么情况下应该抛出异常,什么情况下应该返回错误码或者其他特定值。抛出异常应该是一种非常规的处理方式,只在必要的情况下使用。
  6. 在使用嵌套类时,应该考虑将哪些功能归纳在一起,以及哪些功能应该作为一个独立的类来实现。嵌套类的使用应该有助于提高程序的结构性和可读性。
  7. 在使用友元时,应该仔细考虑哪些类或者函数需要访问另一个类的私有成员,只在必要的情况下使用。同时,应该尽量避免破坏封装性,保证程序的可维护性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1381800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

跟着cherno手搓游戏引擎【5】layer(层)、Glad

编写基类层&#xff1a; Layer.h:提供Attach链接、Detach解绑、Update刷新、Event事件、GetName方法 #pragma once #include"YOTO/Core.h" #include"YOTO/Event/Event.h" namespace YOTO {class YOTO_API Layer{public:Layer(const std::string& nam…

【c/python】用GTK实现一个带菜单的窗口

一、用python 在GTK中创建一个带菜单的窗口&#xff0c;可以通过使用Gtk.MenuBar、Gtk.Menu和Gtk.MenuItem组件来构建菜单。以下是一个基本的例子&#xff0c;展示了如何使用Python的PyGObject库创建一个简单的带菜单栏的GTK窗口。 import gi gi.require_version(Gtk, 3.0) f…

在CMake中自定义宏 add_definitions(-DDEBUG)

hehedalinux:~/Linux/loveDBTeacher-v6$ tree . ├── CMakeLists.txt └── test.c0 directories, 2 files hehedalinux:~/Linux/loveDBTeacher-v6$ test.c #include <stdio.h> #define NUMBER 3int main() {int a 10; #ifdef DEBUGprintf("我是一个程序猿,我…

物联网介绍

阅读引言&#xff1a; 本文从多方面叙述物联网的定义以及在物联网当中的各种通信的介绍。 一、物联网的定义 1.1 通用的定义 物联网&#xff08;Internet of Things&#xff0c;IOT&#xff1b;也称为Web of Things&#xff09;是指通过各种信息传感设 备&#xff0c;如传感器、…

docker 安装redis (亲测有效)

目录 1 安装 1 安装 1 将redis 的 tar 包 上传到服务器 上传之后tar 包&#xff0c;将他变成镜像 输入docker images,发现目前是没有镜像的&#xff0c;现在将tar 包变成镜像 docker load -i redis.tar以上就将tar 包变成镜像了 现在在宿主机找一个地方&#xff0c;存放数据…

【Maven】003-基于 IDEA 创建 Maven 工程

【Maven】003-基于 IDEA 创建 Maven 工程 文章目录 【Maven】003-基于 IDEA 创建 Maven 工程一、关于 Maven 工程的 GAVP1、GAVP 简介2、GAV 坐标规范3、Packaging 定义规则 二、基于 IDEA 创建 Maven 工程1、创建 Maven 项目2、创建结果3、项目结构说明 一、关于 Maven 工程的…

机器人技能学习-构建自己的数据集并进行训练

概要 若想训练自己的场景&#xff0c;数据集的重要性不做过多赘述&#xff0c;下面就基于 robomimic 和 robosuite 构建自己的数据集进行讲解&#xff0c;同时&#xff0c;也会附上 train 和 run 的流程&#xff0c;这样&#xff0c;就形成了闭环。 自建数据集 采集数据 采…

linux安装系统遇到的问题

这两天打算攻克下来网络编程&#xff0c;发现这也确实是很重要的一个东西&#xff0c;但我就奇了怪了&#xff0c;老师就压根没提&#xff0c;反正留在我印象的就一个tcp/ip七层网络。也说正好&#xff0c;把linux命令也熟悉熟悉&#xff0c;拿着我大一课本快速过过 连接cento…

【踩坑】flask_uploads报错cannot import name ‘secure_filename‘

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 背景说明 截至目前&#xff0c;用新版的flask实现文件上传(用到flask_uploads库)&#xff0c;会出现这个问题。 问题原因 版本问题&#xff0c;新的werkzeug已经把secure_filename的位置改了。 解决方法 手动修改…

数据结构与算法(十一) 排序算法一

int nArray[] { 8,5,3,2,7 };如下一个数组&#xff0c;现对其进行从小到大排序 选择排序 选择排序&#xff1a;将小的依次放在前面 具象化如下&#xff1a; void swap(int *nSValue,int *nDValue) 交换函数 { int nTempValue 0; nTempValue *nSValue; *nSVal…

RocketMQ5-03RocketMQ-Dashboard和Java客户端访问示例

接上篇02快速部署RocketMQ5.x(手动和容器部署) 已经完成 RocketMQ5.0 环境的部署&#xff0c;就需要对这个环境进行测试&#xff0c;查看集群、写入消息、读取消息等 本篇教你如何使用和查看部署的服务&#xff1a; Docker部署 Dashboard 获取镜像并下载部署服务 客户端连接 …

ZooKeeper初探:分布式世界的守护者

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 ZooKeeper初探&#xff1a;分布式世界的守护者 前言Zookeeper的概述分布式系统中的角色和作用&#xff1a; Zookeeper的数据模型Znode的概念和层次结构&#xff1a;Znode的类型和应用场景&#xff1a;…

anoconda 安装报错

表现形式&#xff1a;Output folder: D:\anoconda\Lib Extract: _nsis.py Extract: _system_path.py Output folder: D:\anoconda........................ 解决办法&#xff1a; 网址&#xff1a;Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Sour…

【LabVIEW FPGA入门】使用数字IO卡实现计数器输入功能

方法1&#xff1a; 1.首先需要用一个数字IO的输入FPGA端口&#xff0c;并将其拖入程序框图中&#xff0c;同时创建一个循环。 2.如果想要在循环中实现累加功能&#xff0c;就可以使用移位寄存器。 数字输入的当前值和历史值进行比较&#xff0c;用于一个判断大于&#xff0c;来…

【论文解读】SiamMAE:用于从视频中学习视觉对应关系的 MAE 简单扩展

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://siam-mae-video.github.io/resources/paper.pdf 项目主页&#xff1a;https://siam-mae-video.github.io/ 1.背景 时间是视觉学习背景下的一个特殊维度&#xff0c;它提供了一…

年终关账四大财务处理技巧|柯桥会计做账,财税知识

2023年即将落下帷幕&#xff0c;无数公司最忙碌就是“年终关账“这件事了。 “年终关账”不仅是企业内部结算一年经营结果的事&#xff0c;还与企业所得税汇算清缴息息相关&#xff0c;甚至还可能关乎企业税负高低与企业是否依法纳税&#xff0c;千万不可小觑。 同时&#xff0…

MySQL 管理端口

错误 客户出现 MySQL连接数 超过 最大连接数的现象 ERROR 1040 (HY000): Too many connections 出现该现象&#xff0c;一般的解决方法&#xff1a; 1.修改配置文件中的最大连接数&#xff0c;之后重启数据库 2.如果配置文件中没有设置 连接超时时间的参数。8小时后&#…

平衡小车——编码器

学习目标 了解编码器的构成理解编码器采样原理掌握编码器获取转速信息学习内容 编码器组成 左侧的减速齿轮中间的电机部分右侧的电路板减速齿轮 将电机转速通过齿轮按照一定比例进行降速。 电路板 电路板中,包含了一个圆形磁体,还有两个霍尔传感器。 电机转动时,圆形的磁…

Spring之AOP源码(一)

文章目录 一、动态代理1. 概念2. Cglib动态代理的使用3. JDK动态代理的使用 二、SpringAOP1. 简介2. Spring AOP使用 一、动态代理 1. 概念 动态代理&#xff08;Dynamic Proxy&#xff09;是一种在运行时动态生成代理对象的技术。它是一种设计模式&#xff0c;用于在不修改原…

安卓手机变iOS!

Launcher iOS 16 - 安卓手机秒变iOS Launcher iOS 16 是一款iOS启动器&#xff0c;可以将安卓手机桌面变成iOS样子&#xff0c;还有iOS的开机动画和景深效果&#xff01; 下载链接&#xff1a;【Launcher iOS 16】 ​