封装、继承、多态、重载:C++中的强大特性与代码设计

这里写目录标题

  • 封装
    • C语言封装风格
    • C++封装
  • 继承
  • 多态
    • 多态的实现
    • 虚函数概念:
    • 虚表指针
    • overload
    • overwrite
    • override
    • 抽象类
  • 重载

封装

C++中的封装是一种面向对象编程的概念,它将数据(成员变量)和操作(成员函数)封装在一个类中,通过访问控制来限制对类内部实现的访问。封装提供了类与外部世界之间的接口,隐藏了类的内部实现细节,提高了代码的可维护性和安全性。

在C++中,封装可以通过使用访问修饰符(public、private、protected)来实现:

public(公有)访问修饰符允许类的成员在类的外部被访问,也可以在类的内部被访问。通常将公有成员函数作为类的接口,供外部使用。
private(私有)访问修饰符将类的成员隐藏在类的内部,外部无法直接访问私有成员变量和私有成员函数。通常将私有成员用于实现类的内部逻辑。
protected(保护)访问修饰符与私有访问修饰符类似,但允许派生类(子类)访问基类中的保护成员。
下面是一个简单的封装示例:

class MyClass {
private:int privateData;  // 私有成员变量public:void setPrivateData(int data) {  // 公有成员函数privateData = data;}int getPrivateData() const {  // 公有成员函数return privateData;}
};int main() {MyClass obj;obj.setPrivateData(42);int data = obj.getPrivateData();return 0;
}

在上面的示例中,私有成员变量privateData被封装在类MyClass中,外部无法直接访问。通过公有成员函数setPrivateData和getPrivateData来操作私有成员变量。

封装可以提供更好的代码组织和管理方式,同时也增强了代码的安全性,因为外部代码无法直接修改和访问类的内部数据。

C语言封装风格

当单一变量无法完成描述需求的时候,结构体类型解决了这问题。可以将多个类型打包成一体,形成新的类型,这是c语言中封装的概念。但是,新类型并不包含对数据类的操作,所有操作都是通过函数的方式,去进行封装。

1 #include<iostream>2 #include<string>3 using namespace std;4 5 struct person6 {7     string name;8     int age;9     int height;10 };11 void init(person* p)12 {13     p->name = "jiejie";14     p->age = 20;15     p->height = 130;16 }17 void show(person p)18 {19     cout<<"p.name = "<<p.name<<endl;20     cout<<"p.age = "<<p.age<<endl;21     cout<<"p.height = "<<p.height<<endl;22 }23 int main()24 {25     person per;26     init(&per);27     show(per);28 29     return 0;30 }

把数据放到一起用struct包装,然后把数据以引用或指针的方式传给行为。

C++封装

C++的封装认为C语言的封装不彻底,对于数据和行为分类,没有权限控制。
C++则提供控制选择,将数据和行为放在一起,对内开放数据,逻辑抽象。对外提供接口

  1 #include<iostream>2 using namespace std;3 4 class person5 {   6     public: 7         int num;8         void init()9         {10             cin>>this->num;11             cin>>this->age;12             cin>>this->height;13         }14         void show()15         {16             cout<<num<<endl;17             cout<<age<<endl;18             cout<<height<<endl;19         }20     21     protected:22         int age;23     private:24         int height;25 };26 int main()27 {28     person p;29     p.init();30     p.show();31     return 0;32 }

基本流程:
通过创建一个类,再通过创建类对象 再由对象调用行为,完成需求。

继承

C++中的继承是面向对象编程的一个重要概念,它允许一个类(派生类/子类)从另一个类(基类/父类)继承属性和行为。继承可以通过创建一个新类并从基类派生来实现,新类将自动获得基类的成员变量和成员函数,同时可以添加新的成员或重写基类的成员函数。

继承的主要目的是实现代码的重用和构建类之间的层次关系。在继承关系中,基类被称为超类或父类,派生类被称为子类。
一般定义格式如下:

class 派生类名标识符: [继承方式] 基类名标识符
{
[访问控制修饰符]
[成员声明列表]
};

继承方式有3种,分别为公有型,保护型和私有型,访问控制修饰符也是public,protected,private 类型。
成员声明列表中包含类成员变量以及成员函数,是派生类新增的成员。
“:”是一个运算符,表示基类和派生类之间的继承关系。

C++中的继承有以下几种类型:

公有继承(public inheritance):派生类继承了基类的公有成员和保护成员,并且这些成员在派生类中的访问权限与基类中的一样。派生类的对象可以直接访问基类的公有成员。

私有继承(private inheritance):派生类继承了基类的公有成员和保护成员,但是这些成员在派生类中的访问权限变为私有。派生类的对象不能直接访问基类的公有成员,只能通过派生类的成员函数来间接访问。

保护继承(protected inheritance):派生类继承了基类的公有成员和保护成员,但是这些成员在派生类中的访问权限变为保护。派生类的对象不能直接访问基类的公有成员,只能通过派生类的成员函数来间接访问。

在C++中,使用关键字class或struct来定义一个类,并使用关键字public、private或protected来指定成员的访问权限。

下面是一个简单的继承示例:

class Shape {
public:void draw() {std::cout << "Drawing a shape" << std::endl;}
};class Rectangle : public Shape {
public:void draw() {std::cout << "Drawing a rectangle" << std::endl;}
};int main() {Shape shape;shape.draw();  // 输出:"Drawing a shape"Rectangle rectangle;rectangle.draw();  // 输出:"Drawing a rectangle"return 0;
}

在上面的示例中,Shape类是基类,它有一个公有成员函数draw。Rectangle类是派生类,通过public关键字继承了Shape类。Rectangle类重写了draw函数,实现了自己的绘制行为。在main函数中,我们分别创建了Shape对象和Rectangle对象,并调用了它们的draw函数。

继承是一种强大的代码复用工具,它可以使得类之间的关系更加清晰和有组织。通过继承,派生类可以继承基类的接口和实现,并且可以添加自己的功能或修改基类的行为。

继承是面对对象的主要特性之一,它使一个类可以从现有类中派生,而不必重新定义一个类。

实质:用已有的数据类型创建新的数据类型,并保留已有数据类型的特点,以旧类为基础创建新类,新类包含旧类的数据成员和成员函数。并且·可以在新类中添加新的数据成员和成员函数。
旧类被称为基类或者父类,新类被称为派生类或者子类。

多态

C++中的多态是面向对象编程的一个重要概念,它允许使用指针或引用来处理不同类型的对象,而实际上执行的是根据对象类型动态选择的相关操作。多态性可以提高代码的灵活性、可复用性和可扩展性。

C++中的多态性主要通过虚函数(virtual function)和运行时类型识别(runtime type identification)两个机制来实现:

虚函数:在基类中声明虚函数,并在派生类中进行重写。当通过指向基类的指针或引用调用虚函数时,将根据实际对象的类型来选择正确的函数实现。这种动态选择函数的机制称为动态绑定(dynamic binding)。虚函数通过关键字virtual进行声明。

运行时类型识别(RTTI):C++提供了dynamic_cast和typeid两个运算符来进行运行时类型识别。dynamic_cast用于将基类指针或引用转换为派生类指针或引用,如果转换成功,返回指向派生类的指针或引用;如果转换失败,则返回空指针或抛出bad_cast异常。typeid用于获取表达式的实际类型。

下面是一个简单的多态示例:

#include <iostream>class Shape {
public:virtual void draw() {std::cout << "Drawing a shape" << std::endl;}
};class Rectangle : public Shape {
public:void draw() override {std::cout << "Drawing a rectangle" << std::endl;}
};class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a circle" << std::endl;}
};int main() {Shape* shapePtr;Rectangle rectangle;Circle circle;shapePtr = &rectangle;shapePtr->draw();  // 输出:"Drawing a rectangle"shapePtr = &circle;shapePtr->draw();  // 输出:"Drawing a circle"return 0;
}

在上面的示例中,Shape类有一个虚函数draw,Rectangle和Circle类分别是派生自Shape的两个子类,并重写了draw函数。在main函数中,我们使用指向基类的指针shapePtr来处理不同类型的对象。通过将shapePtr指向Rectangle对象和Circle对象,并调用draw函数,会根据对象的实际类型选择正确的函数实现。

多态性使得我们可以以一种统一的方式来处理不同类型的对象,而不需要关心对象的具体类型。这样可以使代码更具灵活性和可维护性,同时提供了一种机制来实现运行时的动态行为。

多态的实现

静态绑定:在编译期决定
函数重载
运算符重载
模板
动态绑定:在程序运行时执行
虚函数

虚函数概念:

在基类中冠以关键字virtual的成员函数
定义:
virtual函数类型 函数名称(参数列表)
如果一个函数在基类中被声明为虚函数,则它在所有派生类中都是虚函数。
只有通过基类指针或引用调用虚函数才能引发动态绑定
虚函数不能声明为静态
如果一个类要做为多态基类,要将析构函数定义为虚函数

虚表指针

虚函数的动态绑定是通过虚表来实现的
包含虚函数的类头4个字节存放指向虚表的指针

overload

成员函数被重载的特征:
相同的范围(在同一类中)
函数名字相同
参数不同
virtual关键字可有可无

overwrite

覆盖是指派生类函数覆盖基类函数 特征是:
不同的范围
函数名字相同
参数相同
基类函数必须有virtual关键字

override

重定义(派生类与基类)
不同的范围(分贝位于派生类和基类)
函数名与参数都相同,无virtual关键字
函数名相同,参数不同,virtual可有可无

抽象类

作用:
抽象类作为抽象设计的目的而声明,将有关的数据和行为组织在一个继承层次结构中,保证派生类具有要求的行为。
对于暂时无法实现的函数,可以声明为纯虚函数,留给派生类去实现
注意:
抽象类只能作为基类来使用
不能声明抽象类的对象,可以使用抽象类的指针和引用
构造函数不能是虚函数,析构函数可以是虚函数
可以试用指向抽象类的指针支持运行时多态性
派生类中必须实现基类中的纯虚函数,否则被看做一个抽象类

对于一个没有任何接口的类,如果想要将它定义成抽象类,只能将虚构函数声明为纯虚的
通常情况下在基类中纯虚函数不需要实现,例外是纯析构函数要给出实现

重载

在C++中,函数重载(Function Overloading)是指在同一个作用域内,可以定义多个具有相同名称但参数列表不同的函数。通过函数重载,可以根据参数的类型、顺序和个数来区分不同的函数,并且可以为相同的操作提供不同的实现。

函数重载的特点如下:

函数名称相同:重载的函数必须具有相同的名称。

参数列表不同:重载的函数必须具有不同的参数列表,可以通过参数的类型、顺序和个数的不同来区分。

返回值类型不同不足以实现函数重载:函数的返回值类型不能作为重载函数的区分标准,因为函数调用时通常会忽略返回值。

举例如下所示:

#include<iostream>
using namespace std;class interage
{int inter;public:interage(int in){inter = in;};~interage(){};interage& operator++(){++inter;return *this; }interage operator++(int in){interage temp(inter);inter++;return temp;}void display(){cout<<inter<<endl;}};
int main()
{interage in(10);in.display();interage in2 = ++(++in);in2.display();interage in3 = in2++;in3.display();in3.display();return 0;
}

通过函数重载,我们可以在C++中实现更加灵活和易于使用的代码。函数重载允许我们使用相同的函数名,但根据参数的类型、顺序和个数来区分不同的函数。这样,我们可以提供不同的函数实现来处理各种情况,而无需为每种情况编写不同的函数名称。

函数重载使得代码更具可读性和可维护性,同时提供了一种方便的方式来进行函数扩展和适应不同的需求。然而,在使用函数重载时,需要注意避免产生歧义或混淆,确保函数之间的区分明确。

总而言之,函数重载是C++中一个强大的特性,可以使代码更加灵活和易于使用,为我们提供了更多的选择和可能性。合理地利用函数重载,可以使我们的代码更加清晰、高效,同时提高开发效率和代码的可维护性。

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

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

相关文章

23种设计模式Python版

目录 创建型模式简单工厂模式工厂方法模式抽象工厂模式单例模式原型模式建造者模式 结构型模式适配器模式桥接模式组合模式装饰器模式外观模式享元模式代理模式 行为型模式职责链模式命令模式解释器模式迭代器模式中介者模式备忘录模式观察者模式状态模式策略模式模板方法模式访…

改进YOLO系列 | YOLOv5/v7 更换主干网络之 ResNet50/ResNet101

论文地址:https://arxiv.org/abs/1512.03385v1 更深层的神经网络更难以训练。我们提出了一个残差学习框架,以便于训练比以往使用的网络更深层的网络。我们明确地将层重构为学习相对于层输入的残差函数,而不是学习无参考的函数。我们提供了全面的实证证据,表明这些残差网络…

接口测试工具Postman接口测试图文教程

一、前言 在前后端分离开发时&#xff0c;后端工作人员完成系统接口开发后&#xff0c;需要与前端人员对接&#xff0c;测试调试接口&#xff0c;验证接口的正确性可用性。而这要求前端开发进度和后端进度保持基本一致&#xff0c;任何一方的进度跟不上&#xff0c;都无法及时完…

APP UI自动化测试常见面试题,或许有用呢~

1.Android APP 内存不足时&#xff0c;如何获得内存&#xff1f; 系统优先结束被挂起&#xff08;暂停&#xff09;的进程&#xff0c;释放内存。 2.APP 测试常见问题有哪些&#xff1f;原因有哪些&#xff1f; 常见的有 crash、ANR&#xff08;应用无响应、卡死&#xff09…

STM32G030F6P6读写flash失败问题(HAL)

STM32G030是F0系列的升级版&#xff0c;其在性能上比F0要好很多&#xff0c;具体G0参数如下&#xff1a; 最开始做项目选用的单片机是STM32F030F4P6&#xff0c;但是在后期使用中发现&#xff0c;我的FLASH&#xff08;16K&#xff09;不够用了&#xff0c;就选择了STM32G030F6…

【Matlab】LSTM长短期记忆神经网络时序预测算法(附代码)

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88688439 一&#xff0c;概述 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种常用的循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;结构&#xff0c;由于其对于…

java常见面试题:什么是泛型?泛型有哪些应用场景?

泛型是程序设计语言的一种特性&#xff0c;它允许程序员在强类型程序设计语言中编写代码时定义一些可变部分&#xff0c;那些部分在使用前必须作出指明。 泛型的应用场景主要包括以下几个方面&#xff1a; 集合类和数据结构&#xff1a;泛型最常见的用途是在集合类&#xff0…

ros2基础学习13 DDS 通信得学习

ROS2中最为重大的变化——DDS&#xff0c;我们在前边课程中学习的话题、服务、动作&#xff0c;他们底层通信的具体实现过程&#xff0c;都是靠DDS来完成的&#xff0c;它相当于是ROS机器人系统中的神经网络。 通信模型 DDS的核心是通信&#xff0c;能够实现通信的模型和软件框…

科技云报道:2024年六大科技趋势前瞻,最热门的技术都在这里了!

科技云报道原创。 物之生也&#xff0c;若骤若驰&#xff0c;无动而不变&#xff0c;无时而不移。 技术创新的步伐丝毫没有放缓的迹象&#xff0c;在这个日新月异的时代&#xff0c;科技创新在改变人们生活、推动社会进步方面扮演着关键的角色。2024年有望成为又一个开创性的…

不停止业务的情况下优化 Elasticsearch Reindex

在使用 Elasticsearch 时,我们总有需要修改索引映射的时候,这时我们只能进行 _reindex。事实上,这是一个相当昂贵的操作,因为根据数据量和分片数量,完整复制一个索引可能需要几个小时。 花费的时间不是大问题,但更严重的是,它会影响生产环境的性能甚至功能。 相信大家…

高效管理文件夹:使用重命名进行文件夹名称大小写转换的技巧

在计算机管理中&#xff0c;文件夹名称的大小写规范是一个经常被忽视的细节。然而&#xff0c;文件夹名称的大小写有时可能会影响工作流程&#xff0c;例如在某些文件搜索或识别过程中。掌握文件夹名称大小写转换的技巧&#xff0c;可以更高效地管理文件夹。现在一起来看看云炫…

yolov8 速度测试

yolov8 速度测试 T4显卡 1&#xff0c;1280 1280 yolov8x6 推理速度 Speed: 7.4ms preprocess, 156.8ms inference, 1.1ms postprocess per image at shape (1, 3, 960, 1280) 2.fp16打开 0: 960x1280 1 bj_bpmh, 159.6ms Speed: 7.5ms preprocess, 159.6ms inference, 1.2m…

分布式定时任务Xxl_Job详细使用手册

看了很多网上的版本&#xff0c;思路描述的都不是很清晰&#xff0c;都只是几步操作就完成了&#xff0c;看效果&#xff0c;导致容易走入弯路&#xff08;不排除是自己理解能力把&#xff09;&#xff0c;最开始以为是把admin模块集成到项目&#xff0c;后来测试了会&#xff…

我敢说,这是你必会的网络端口知识

下午好&#xff0c;我的网工朋友&#xff0c;新年快乐&#xff01; 端口是计算机网络技术中非常基础的概念&#xff0c;不管是网络实施、运维、还是软件开发&#xff0c;总是能听到端口二字。 理论上来说&#xff0c;端口数最多可以有65535个。 端口概念在网络技术中&#x…

结构体的一些小技巧

有一天在写洛谷的一道题的时候&#xff0c;我想出来大概思路&#xff0c;但是有几步我想破头也无法实现。 后来看了题解&#xff0c;发现原来结构体可以这样使用。 比如&#xff0c;现在有一个结构体&#xff1a; struct person {char gender;int age, high, height; };它表…

【WPF.NET开发】弱事件模式

本文内容 先决条件为什么要实现弱事件模式&#xff1f;应该由谁实现弱事件模式&#xff1f;如何实现弱事件模式 在应用程序中&#xff0c;附加到事件源的处理程序可能不会与将处理程序附加到源的侦听器对象一同销毁。 这种情况下会导致内存泄漏。 Windows Presentation Found…

DDoS 攻击并不是全部来自于PC组成的僵尸网络

DDoS&#xff0c;分布式拒绝服务攻击&#xff0c;是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击&#xff0c;或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。很多人会以为DDoS 攻击&#xff0c;全都是攻击者控制PC肉鸡发起的攻击…

ELF文件信息一览

准备开个专栏&#xff0c;记录《从零开始实现链接器》的学习过程&#xff0c;先占个坑。 之前一直想把自己的学习过程记录在个人博客网站上&#xff0c;但这个要自己维护&#xff0c;上传图片什么的比较麻烦。关键是没有人互动&#xff0c;自己也没有怎么去看&#xff0c;慢慢的…

柯桥专业会计学校之相关财税知识,2023年新版增值税税率表

一、增值税税率 一般纳税人增值税税率&#xff1a;13%&#xff0c;9%&#xff0c;6%&#xff0c;0%&#xff0c;都适用于哪些项目&#xff1f;我们具体来看&#xff1a;&#xff08;目前小规模纳税人3%征收率减按1%执行&#xff09; 二、扣除率 扣除率是指增值税计征中法定扣除…

什么是DDOS 攻击?常见的DDOS攻击有哪些?

什么是DDoS攻击&#xff1f; DDoS攻击&#xff08;分布式拒绝服务攻击&#xff09;是一种旨在使计算机或网络资源不可用的恶意尝试。它通过使用多个受感染计算机&#xff08;称为僵尸网络&#xff09;同时向目标发送大量流量来实现这一目的&#xff0c;从而使目标不堪重负并崩溃…