C++中的面向对象到底是什么

C++中的面向对象到底是什么

对象嘛,就和大家都有的对象一样,两只眼睛、一个嘴巴、两条腿……
对不起跑题了,C++的面向对象中的对象可不是显示中的对象哦,但是有一些相似之处,有对象的同学可以参考着去学习C++面向对象的概念,没有对象的同学……那就先new一个出来(手动滑稽
在这里插入图片描述

面向对象的概念

对象是对某一类事物的抽象表示,同时具有属性和方法。属性就是这个对象拥有的一些特征,方法就是这个对象可以进行的一些行为。

例如我们大学都必会的“学生管理系统”,用C++面向对象的思想就是,我们把学生看作对象,这个对象拥有身高、姓名、学号、班级、成绩等属性,同时还有修改班级、设置成绩等方法

再例如人也是一个对象,拥有性别、姓名、户籍地等属性,拥有吃饭、睡觉、唱歌等方法。

在C++中,万物皆可对象,也就是我们在开发之前进行系统设计的时候,要从面向对象的角度出发,先考虑如何通过对象的角度去解决问题,规划好各个对象之间的逻辑关系(例如老师可以管理学生,领导可以管理老师等等)。

在C++中,对象是使用类来实现,例如下面的Person类

class Person
{
public:void eat();void sleep();private:int age;string name;string sex;float hight;
}

对象和实例

对象是对某一类事物的抽象表示,也就是总称;实例就是这个对象的一个具体的例子,同时也是对象,比如人是对象,小明就是对象的一个实例,但是小明也是人。
例如,女朋友是对象,拥有身高、体重、性格、饭量等属性,还有帮你洗衣服、给你做饭、想你撒娇等方法,女朋友A是对象的一个实例,女朋友B也是对象的一个实例,她们的属性数据不同。

我们平常看到的“对象的实例化”、“实例化一个对象”其实都是一个意思,就是由抽象的对象去创建一个个具体的“对象”,因为对象实例化产生的实例也是对象。

在C++中,对象的实例化有下面几种方式

默认构造函数实例化(栈上)

这是最常见的方式,使用类的默认构造函数创建对象。默认构造函数没有参数,它会在对象创建时被调用。下面这种方式是在栈上实例化。

class MyClass {
public:MyClass() {// 构造函数的实现}
};int main() {MyClass obj; // 使用默认构造函数实例化对象return 0;
}

带参数的构造函数实例化(栈上)

如果类定义了带参数的构造函数,你可以在实例化对象时传递参数给构造函数,下面这种方式在栈上实例化

class MyClass {
public:MyClass(int value) {// 构造函数的实现}
};int main() {MyClass obj(42); // 使用带参数的构造函数实例化对象return 0;
}

无参数动态内存分配实例化(堆上)

使用 new 运算符可以在堆上动态地分配内存,并调用构造函数来实例化对象,需要使用delete手动删除实例化的对象。

class MyClass {
public:MyClass() {// 构造函数的实现}
};int main() {MyClass* obj = new MyClass(); // 使用动态内存分配实例化对象// 使用对象delete obj; // 释放内存return 0;
}

有参数动态内存分配实例化(堆上)

使用 new 运算符可以在堆上动态地分配内存,并调用构造函数来实例化对象,需要使用delete手动删除实例化的对象。

class MyClass {
public:MyClass(int value) {// 构造函数的实现}
};int main() {MyClass* obj = new MyClass(10); // 使用动态内存分配实例化对象// 使用对象delete obj; // 释放内存return 0;
}

在栈上实例化和在堆上实例化的区别

内存管理:

  • 堆上实例化:使用 new 运算符在堆上动态分配内存,对象的生存期由程序员手动控制。需要显式使用 delete 运算符来释放内存,否则可能导致内存泄漏。
  • 栈上实例化:对象在函数的栈帧上自动分配内存,对象的生存期与其所在的作用域相对应。当对象离开作用域时,内存会自动被释放,无需手动管理。

对象访问:

  • 堆上实例化:通过指针来访问对象,需要使用箭头运算符(->)来访问对象的成员。
  • 栈上实例化:通过对象名来直接访问对象的成员。

生命周期:

  • 堆上实例化:对象可以在程序的任意位置创建和销毁,生存期由程序员控制。对象可以在多个作用域中共享。
  • 栈上实例化:对象的生存期与其所在的作用域相对应,当对象离开作用域时,自动被销毁。

对象的大小:

  • 堆上实例化:对象的大小可以是动态的,取决于对象的成员和继承关系。对象的大小可能会影响堆的碎片化。
  • 栈上实例化:对象的大小在编译时确定,通常是固定的。

对象初始化:

  • 堆上实例化:在堆上实例化对象时,可以调用带参数的构造函数来初始化对象。
  • 栈上实例化:在栈上实例化对象时,会自动调用构造函数来初始化对象。

面向对象的三大特性

封装

将一些属性和相关方法“集成”在一个对象中,对外隐藏内部具体的实现细节,外界只需要根据内部提供的接口去使用就可以。

上面的类就体现了封装的概念,实例化一个对象之后,只需要调用它的方法即可,不需要关心内部的实现细节。

继承

我们先明确几个术语:

  • 基类(父类)(Base Class):被继承的类。
  • 派生类(子类)(Derived Class):从基类继承得到的类。
  • 进一步派生的类(孙子类)(Further Derived Class):从派生类再次派生出的类,可以视为“孙”类或更远的后代。

继承就是把父类(也称为基类)的属性和方法继承过来,继承也分为三种,分别是公有继承(public)、保护继承(protected)和私有继承(private)

  • 通过公有继承,基类的公有成员和保护成员在派生类中保持其原有的访问权限(公有成员仍为公有,保护成员仍为保护),而基类的私有成员不能直接被派生类访问,但可以通过基类提供的公有或保护方法来访问。
  • 通过保护继承,基类的公有和保护成员在派生类中都成为保护成员。私有成员仍然保持私有,不可直接访问。
  • 通过私有继承,基类的公有和保护成员在派生类中都成为私有成员。基类的私有成员仍然保持私有,不可直接访问。私有继承通常被用于实现细节的隐藏和复用基类的实现而不是其接口。

详细说下保护继承:
在保护继承中,基类的公有和保护成员在派生类中都成为保护成员,意味着这些成员在派生类内部是可访问的,但是不能被派生类的对象直接访问。也就是说,你不能通过派生类的对象直接访问这些从基类继承来的成员,因为它们在派生类中的访问级别是保护的,而不是公有的。

当我们继续从这样的派生类再派生出新的类时,这些保护成员依然保持保护状态,这意味着在这个新的、进一步的派生类中,这些成员仍然是可访问的。因为保护成员的特性就是允许在类的内部以及这个类的派生类中访问,但不允许通过类的对象进行访问。

假设有三个类:Base、Derived(从Base通过保护继承得来)和FurtherDerived(从Derived类继承得来)。
Base类有一个公有成员和一个保护成员。

由于是保护继承,Derived类中这些成员都成为保护成员,Derived类可以访问这些成员,但Derived类的对象不能直接访问这些成员。

FurtherDerived类,作为Derived的派生类,同样可以访问这些从Base继承来的保护成员,因为保护成员在整个继承链中都保持保护状态,使得它们可以在任何派生类中被访问,但不可以被类的对象直接访问。

这种机制允许在类的内部和其派生类之间共享成员,同时阻止外部访问,从而在一定程度上封装和保护了这些成员。

多态

多多态是面向对象编程中的一个核心概念,它指的是不同类的对象对同一消息的响应方式不同,或者说,同一个接口可以被不同的对象以不同的方式实现。在C++中,多态主要通过虚函数来实现,它允许使用指向基类的指针或引用来调用派生类的方法。

多态主要分为两种类型:静态多态和动态多态。

  • 静态多态(编译时多态):通过函数重载和运算符重载实现。它在编译时决定了使用哪个函数,依赖于参数的数量和类型。
  • 动态多态(运行时多态):主要通过虚函数实现。在运行时根据对象的实际类型来调用相应的方法,实现了接口的统一和行为的多样。

动态多态的实现依赖于以下几个关键点:

  • 虚函数(Virtual Function):在基类中用virtual关键字声明的函数。派生类可以重写(Override)这个函数以提供特定的实现。
  • 纯虚函数(Pure Virtual Function):形式为virtual ReturnType FunctionName() = 0;。含有纯虚函数的类称为抽象类(Abstract Class),不能直接实例化。
  • 基类指针或引用:可以指向派生类的对象,并通过这个指针或引用调用虚函数,实现动态绑定(Dynamic Binding),即在运行时决定调用哪个版本的虚函数。

多态内容较多,我在后面的博客会详细说名这部分内容。

访问权限修饰符

解释一下几种称呼:

  • 派生类:继承自父类的子类;
  • 类外部:除了类内部定义和派生类之外的任何地方。在类外部只能访问该类对象的public成员;
  • 类内部:指的是在类的定义内部,你可以访问所有public、private和protected成员。

public

公有成员可以在类的内部、派生类以及类的外部访问。使用public修饰的成员在类的接口中非常常见,因为它们是类与外界交互的部分。

protected

保护成员可以在类的内部和派生类中访问,但不能在类的外部直接访问。保护访问修饰符在基类中定义成员时特别有用,这些成员需要对派生类可见,但对其他外部类或函数不可见。

protected成员不能被类的对象访问,因为类的对象属于类外部

private

私有成员只能在类的内部访问。即使是该类的派生类也无法访问私有成员。私有访问限制是类封装的一个重要方面,它防止了外部对类内部实现细节的直接访问。

访问权限总结

访问修饰符类内部类外部派生类
public可访问可访问可访问
protected可访问不可访问可访问
private可访问不可访问不可访问

为什么要面向对象编程

面向对象编程,真的是为开发者带来了极大的便利。
在这里插入图片描述
封装我们通过将一类事物封装成一个对象,隐藏内部的实现细节,我们只需要为这个对象设计一组接口,开发者可以直接调用此接口去进行其他操作,而不必思考这个接口内部的实现细节。这种信息隐藏的特性有助于降低系统复杂性,提高模块的独立性,从而使得软件易于理解、修改和扩展。

继承允许新创建的类(派生类)继承现有类(基类)的属性和方法。这促进了代码的重用,允许新的类重写或扩展基类的功能。通过继承,可以创建出具有层次结构的类体系,有助于组织和管理复杂的代码。

多态可以使得一个接口可以用不同的方式来实现,增加了代码的灵活性和可扩展性。这也是实现插件架构和依赖注入等设计模式的关键。

此外,封装、继承和多态也支持了代码的低耦合性,这使得修改和维护现有代码更加容易。

另外,类的抽象性允许开发者专注于高层次的操作,而不是底层的实现细节。通过定义具有通用功能的类,可以创建抽象的表示,这减少了代码的复杂性并提高了代码的可理解性。并且面向对象的概念支持软件工程的基本原则,如模块性、封装性和复用性。这些原则是构建大型系统和复杂应用程序的基石,有助于降低软件开发和维护的复杂性。

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

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

相关文章

HackTheBox-Machines--Builder

文章目录 1 端口扫描2 测试思路3 漏洞测试 Builder测试过程 1 端口扫描 nmap -sC -sV 10.129.230.2202 测试思路 系统开启了22和8080端口,22端口无账号密码,测试方向主要从8080的jenkins服务开始测试。 在测试开源系统时,可以下载源代码或本地…

3、jvm基础知识(三)

如何判断堆上的对象没有被引用? 常见的有两种判断方法:引用计数法和可达性分析法。 引用计数法会为每个对象维护一个引用计数器,当对象被引用时加1,取消引用时减1。 引用计数法的优点是实现简单,缺点有两点&#xff1…

电机选型与直线模组(简化版)

2-1电机分类和普通电机选型 1、电机及其原理的基本认知: 电动机我们平时简称电机,大部分情况下指的都是通电后,输出轴会旋转运动的设备。即将电能转换为机械能,供我们使用以驱动机构运行。电机简单的讲,其实就是一个…

梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码

源码简介 最新梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码下载 梨花带雨播放器基于thinkphp6开发的XPlayerHTML5网页播放器前台控制面板,支持多音乐平台音乐解析。二开内容:修复播放器接口问题,把接口本地化,但是集成外链播放器…

【Qt】常用控件(输入类)

目录 一、Line Edit二、Text Edit三、ComBo四、DateTimeEdit五、Slider 一、Line Edit QLineEdit 用来表示单行输入框,可以输入一段文本,但是不能换行。 属性说明test输入框中的文本inputMask输入内容格式约束maxLength最大长度frame是否添加边框echoM…

harbor api v2.0

harbor api v2.0 v2.0 v2.0 “harbor api v2.0”与v1区别较大,此处harbor也做了https。另外,通过接口拿到的数据也是只能默认1页10个,所以脚本根据实际情况一页页的循环抓取数据 脚本主要用于统计repo(仓库)、image,以及所有镜像…

【新手适用】手把手教你从零开始实现一个基于Pytorch的卷积神经网络CNN二: 如何训练模型,内附详细损失、准确率、均值计算

手把手教你从零开始实现一个基于Pytorch的卷积神经网络CNN(新手适用)一: model.py:创建模块-CSDN博客 从零开始实现一个基于Pytorch的卷积神经网络 - 知乎 目录 1 设备device定义 2 训练模型定义 3 开始训练 3.1 step、batch…

4.机器学习-十大算法之一线性回归算法(LinearRegression)案例讲解

机器学习-十大算法之一线性回归算法案例讲解 一摘要二个人简介三什么是线性回归四LinearRegression使用方法五糖尿病数据线性回归预测1.数据说明2.导包3.导入数据4.脱敏处理5.抽取训练数据和预测数据6.创建模型7.预测8.线性回归评估指标9.研究每个特征和标记结果之间的关系.来分…

职场成功的关键:提升软实力,成就非凡事业

在竞争激烈的职场中,专业技能固然重要,但软实力同样不可或缺。要想在职场中脱颖而出,实现事业上的成功,我们需要在提升软实力上下功夫。本文将探讨职场软实力的内涵及其在职场成功中的作用,并提供一些建议,…

解决Quartus与modelsim联合仿真问题:# Error loading design解决,是tb文件中没加:`timescale 1ns/1ns

解决Quartus与modelsim联合仿真问题:# Error loading design解决,是tb文件中没加:timescale 1,一直走下来,在modelsim中出现了下面问题2,rtl文件、tb文件2.1,rtl代码2.2,tb测试2.3&a…

java Web实现用户登录功能

文章目录 一、纯JSP方式实现用户登录功能(一)实现思路1、创建Web项目2、创建登录页面3、创建登录处理页面4、创建登录成功页面5、创建登录失败页面6、编辑项目首页 (三)测试结果 二、JSPServlet方式实现用户登录功能(一…

校园通勤车可视化系统的设计与实现

1.需求分析: 校园通勤车可视化系统的设计与实现,不用管什么可视化,就是一个小程序就是可以知道校园车的路线,然后往简单了弄就可以。 校园通勤车可视化系统的设计与实现,不用管什么可视化,就是一个小程序…

【C/C++】C++学籍信息管理系统(源码+报告)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

【threejs】较大物体或shape的贴图较小问题处理方法

问题 有的场景内相对体型差距过大的物体(如山地 海洋等)由于尺寸问题,加载贴图过于小,同时shader也无法完全展示,如图 我们可以获取物体的uv,进行缩放使得贴图可以完全展开 如果uv是乱的 可以用xyz坐标最…

【Redis】MISCONF Redis is configured to save RDB snapshots报错解决方案

【Redis】MISCONF Redis is configured to save RDB snapshots报错解决方案 大家好 我是寸铁👊 总结了一篇【Redis】MISCONF Redis is configured to save RDB snapshots报错解决方案✨ 喜欢的小伙伴可以点点关注 💝 前言 今天在登录redis时&#xff0c…

python_绘图_多条折线图绘制_显示与隐藏

1. 需求 给定一个二维数组 100行, 5列, 每一列绘制一条折线, 横轴为行索引, 纵轴为对应位置的值, 绘制在一个子图里面, 使用python plot, 使用随机颜色进行区别添加显示和隐藏按钮, 可以对每条折线进行显示和隐藏 2. 代码 import numpy as np import matplotlib.pyplot as p…

为什么说FMEA是最主要的可靠性设计工具?——FMEA软件

免费试用FMEA软件-免费版-SunFMEA FMEA,即故障模式与影响分析(Failure Modes and Effects Analysis),是一种预防性的质量工具,广泛应用于各种工程领域,特别是在产品设计和制造过程中。它通过对产品或过程中…

4月2日 qt密码生成小程序(可选择生成密码的格式),基于Python框架下的pyqt6

4月2日 密码生成小程序 代码展示: import stringfrom PyQt6.QtWidgets import (QApplication, QDialog,QMessageBox ) from untitled import Ui_PasswordGender import sys import string # py模块含有字符 import randomclass MyPasswordGenerate(Ui_Password…

快速入门Linux,Linux岗位有哪些?(一)

文章目录 Linux与Linux运维操作系统?操作系统图解 认识LinuxLinux受欢迎的原因什么是Linux运维Linux运维岗位Linux运维岗位职责Linux运维架构师岗位职责Linux运维职业发展路线计算机硬件分类运维人员的三大核心职责 运维人员工作(服务器)什么…

python爬虫----了解爬虫(十一天)

🎈🎈作者主页: 喔的嘛呀🎈🎈 🎈🎈所属专栏:python爬虫学习🎈🎈 ✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天…