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可访问不可访问不可访问

为什么要面向对象编程

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

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3. WiFi基本原理

1. WiFi简介 WiFi的全称是Wireless Fidelity。它是一种无线网络通信技术,由Wi-Fi联盟拥有,目的是改善基于IEEE 802.11标准的无线网络产品之间的互通性,允许电子设备在没有物理连接的情况下进行高速数据传输。此外,WiFi也被视为IE…

SpringCloudAlibaba服务消费者调用nacos服务报错:java.net.UnknownHostException: xxx

确保服务情况正常 通过服务名字调用(注意不需要添加端口号) RequestMapping("/add") public String add() {String url "http://stock-nacos/stock/reduce";String result restTemplate.getForObject(url, String.class);System.out.println("下单…

Vue性能优化--gZip

一、gZip简单介绍 1.1 什么是gzip gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前主流的浏览器,Chro…

UE4 方块排序动画

【动画效果】 入动画: 出动画: 【分析】 入动画:方块动画排序方式为Z字形,堆砌方向为X和Y轴向 出动画:方块动画排序方式为随机 【关键蓝图】 1.构建方块砌体 2.入/出动画

解锁AI提示工程新纪元:你的提问是关键!

文章目录 一、AI的潜力:无尽的宝藏等待解锁二、提问的艺术:挖掘AI潜力的关键三、AI的回应:超越预期的答案与启示四、提问的力量:推动AI不断进步与发展五、用提问开启与AI的智慧对话《向AI提问的艺术:提示工程入门与应用…

AdaBoost算法详解自用笔记(1)二分类问题举例分析

AdaBoost算法详解自用笔记(1)二分类问题举例分析 提升方法的思路 AdaBoost作为一种提升方法,其需要回答两个问题:一是每一轮如何改变训练数据的权重或概率分布;二是如何将弱分类器组合成一个强分类器。对于第一个问题…

【御控物联】JavaScript JSON结构转换(7):数组To数组——键值互换属性重组

文章目录 一、JSON结构转换是什么?二、案例之《JSON数组 To JSON数组》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么? JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换,生成新的JS…

《FDTD Solutions仿真全面教程:从基础入门到论文复现》

2024年5月11日-5月12日 2024年5月18日-5月19日 适用人群: 1.光电工程、物理学、材料科学等相关专业的硕博研究生及科研人员 2.工作于微纳光学、超构材料、光通信、光电子器件等领域的研发工程师 3.对光电仿真技术有浓厚兴趣且希望提升自身科研能力的高校教师和企业研…

ArcGIS操作(四)

任务: 根据江苏省夜间灯光影像完成数据处理与分析查阅统计年鉴数据以提取建成区空间分布位置完成建成区重心转移轨迹 步骤: 这里选取江苏省2000年、2004年、2008年夜光数据进行分析 加载影像 掩膜提取 投影 栅格转面 融合 栅格转面数据时分冗余&…

2024年,短期PMP备考上岸攻略!

今天分享一个PMP备考经验,正在备考PMP的小伙伴,咱们共勉! 第一周、阅读教材 之前是第六版教材,花了很长时间阅读和梳理框架。现在是第七版教材,内容少了很多,只有300多页,不会特别耗时间&…

数据结构进阶篇 之 【堆的应用】(堆排序,TOP-K问题)详细讲解

所有人都关心我飞的高不高,只有我妈关心我翅膀硬不硬 一、堆的应用 1. 堆排序 1.1 建堆 1.2 利用堆删除思想来进行排序 2.TOP-K问题 二、完结撒❀ –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–…

GPT-5:更强的ChatGPT!将在高级推理功能上实现重大进步!GPT-5有哪些功能作用?

自 Claude 3 发布以来,外界对 GPT-5 的期待越来越强。毕竟Claude 3已经全面超越了 GPT-4,成为迄今为止最强大模型。 对于即将发布的GPT-5,有哪些期待? 目前来说,GPT-5的将具备哪些新能力? GPT-5性能进步…

SA2601A 矽塔SYTATEK双NMOS半桥栅极驱动芯片 600V单相

SA2601A是一款针对于双NMOS的半桥栅极驱动芯片,专为高压、高速驱动N型功率MOSFET和IGBT设计,可在高达600V电压下工作。 SA2601A内置VCC和VBS欠压(UVLO)保护功能,防止功率管在过低的电压下工作,提高效率。 SA2601A输入脚兼容3.3-15…

安装pytorch3d 0.3.0遇到的一些问题

官网:PyTorch3D A library for deep learning with 3D datahttps://pytorch3d.org/最新版本pytorch3d/INSTALL.md at main facebookresearch/pytorch3d (github.com) 之前版本Releases facebookresearch/pytorch3d (github.com) 找到需要的版本,例如…

2024春算法训练3——数组与字符串

一、题解 1、A-[NOIP2013]记数问题_2024春算法训练3——数组与字符串 (nowcoder.com) 直接暴力用一个哈希表存每个数出现的次数&#xff0c;最坏的时间时间复杂度为7*10^7&#xff08;实际上比这个数要小&#xff09;&#xff1b;代码如下&#xff1a; #include<iostream…

SSL安全证书多少钱?

SSL安全证书多少钱&#xff1f;单域名、多域名与通配符SSL证书的全面对比与价格分析。SSL&#xff08;Secure Sockets Layer&#xff09;证书作为一种加密技术&#xff0c;能够确保网站数据传输的安全性和可靠性&#xff0c;对于提升网站信誉和保护用户隐私具有至关重要的作用。…

niushop单商户V5多店版源码分享三端uniapp打包方法包括PC端_小程序或h5端打包_收银端打包_APP端打包_商户端

目前多店版有四端uniapp&#xff0c;包括PC端uniapp&#xff0c;商家端uniapp&#xff0c;收银端uniapp&#xff0c;门店手机端uniapp&#xff0c;下面我总结下这些端的打包流程希望能帮助到大家&#xff0c;需要交流的可以看我昵称或者点我头像关注我分享代码和教程 一.niush…

kettle介绍-参数变量

ETL中为什么使用参数变量 实现ETL的复用D,Q,P环境不同,使用变量方便发布有的条件需要外部传入增量ETL灵活性强 kettle中参数变量种类 Environment VariablesKettle VariablesInternal VariablesTransformation中的变量Job中的变量 Environment Variables 通过Set Environm…

QT - 日志:qDebug/qInfo/qWarning/qCritical

篇一、日志打印函数 头文件&#xff1a; #include <QDebug> 代码&#xff1a;qDebug()<<"hello world!"; 其他打印级别&#xff1a; qInfo(): 普通信息 qDebug(): 调试信息 qWarning(): 警告信息 qCritical(): 严重错误 qFatal(): 致命错误 1. qDebug…

FSH6罗德与施瓦茨FSH6频谱分析仪

181/2461/8938产品概述&#xff1a; R&S FSH6频谱分析仪坚固耐用、方便易用&#xff0c;专为野外使用而设计。它重量轻、操作简单、设计合理且具有大量测量功能&#xff0c;是任何需要高效测量仪器进行户外工作的人不可或缺的工具。 R&S FSH6是一款手持式频谱分析仪&…