C++三大特性及应用

C++三大特性

面向对象程序设计(OOP)是一种编程范式,它使用“对象”来设计软件。在OOP中,对象是类的实例,类包含数据(属性)和可以对数据执行操作的方法(行为)。

面向对象的核心概念包括封装、继承和多态(C++三大特性)。

什么是类?

在C++中,类是一种用户定义的数据类型,它可以包含数据成员和函数成员。数据成员用于存储与类相关的状态,而函数成员可以定义对这些数据进行操作的方法。可以把类想象为一个蓝图,根据这个蓝图可以创建对象,这些对象在内存中是类的实例。

比如说,我们可以定义一个Car类来表示汽车。这个类可以有数据成员如brand、color和maxSpeed来存储汽车的品牌、颜色和最高速度等属性。同时,Car类可能有函数成员如accelerate()和brake()来定义汽车加速和刹车的操作。

在现实生活中,每辆汽车都是根据汽车制造商设计的蓝图制造出来的,蓝图定义了汽车的特性和功能,类似地,在编程中,我们根据类创建对象来表示现实世界中的各种事物和概念。

class A
{
private:int a;
public:void print(){cout << "a=" << a << endl;}A(int a){this->a = a;}
};

封装

封装(encapsulation):是指将数据(属性)和操作数据的代码(方法)打包在一起,形成一个独立的对象。这样可以隐藏对象的内部细节,只暴露必要的操作接口。比如,一个汽车对象封装了引擎、变速器等细节,只提供加速和刹车等接口。

封装实际就是为类中的函数和变量设置访问权限。访问权限包括public,private,protect。其中类对象的默认访问控制权限为private。

(1)public(共有),所有类均可访问

(2)protected(保护),可以被自身和子类访问

(3)private(私有),只能自身和友元函数访问

说明:

(1)public成员可以在类外直接访问。

(2)protected和private成员在类外(在此将这两种限定符都可以看成是私有的,在继承出区别)不能够访问。

(3)它们的作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。

(4)class的默认访问权限是private,而struct为public型(因为struct要兼容C)。C++常用的是class

(5)类外:即脱离了类的作用域或者说访问时不在类的成员函数中。

继承

继承:继承是面向对象软件技术当中的一个概念。如果一个类B继承自另一个类A,就把这个B称为A的子类,而把A称为B的父类。**继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。

子类继承基类后,可以创建子类对象来调用基类函数,变量等。继承包括以下形式:

(1)单一继承:继承一个父类,这种继承称为单一继承,一般情况尽量使用单一继承,使用多重继承容易造成混乱易出问题

(2)多重继承:继承多个父类,通过逗号进行分隔可以让派生类指定多个基类。例如 狗:public 哺乳动物,public 犬科动物

(3)菱形继承:多重继承掺杂隔代继承1-n-1模式,此时需要用到虚继承,例如 B,C虚拟继承于A,D再多重继承B,C,否则会出错

继承的代码表示为:

class B : public A
{
private:int b;
public:void print(){cout << "b=" << b << endl;}B(int a, int b) : A(a){this->b = b;}
};

继承方式规定了如何访问继承的基类的成员。继承方式指定了派生类成员以及类外对象对于从基类继承来的成员的访问权限

继承权限:子类继承基类除构造和析构函数、基类的重载运算符、基类的友元函数以外的所有成员,继承可以扩展已存在的代码,目的也是为了代码重用。

另外,继承可分为接口继承和实现继承:

(1)普通成员函数的接口总是会被继承:  子类继承一份接口和一份强制实现

(2)普通虚函数被子类重写     :  子类继承一份接口和一份缺省实现

(3)纯虚函数只能被子类继承接口  :  子类继承一份接口,没有继承实现

访问权限图如下:

友元函数是C++中的一个概念,它允许某些非成员函数访问类的私有成员和保护成员,这通常是为了提高程序的运行效率。友元函数虽然在语法上看起来像普通的函数,但在定义时需要在类体内使用关键字friend进行说明,以表明它不是该类的成员函数,但可以访问类的私有和保护成员。(1)(2)

友元函数的特点和注意事项如下:

  • 特点。友元函数可以访问类中的私有和保护成员,这使得它在某些情况下比类的成员函数更灵活。然而,这也意味着它可能会破坏类的封装性,因为非成员函数现在可以直接访问类的私有部分。

  • 注意事项。友元函数在类中的声明位置(如private、protected、public区域)并不影响其访问权限,友元函数可以在任何位置定义,并且不需要是类的成员函数。友元函数也不能被继承,即父类的友元函数不会自动成为子类的友元函数。

另外,友元关系不具有对称性和传递性,这意味着如果A是B的友元,那么B不一定是A的友元,且A和B的友元关系不会传递到其他类。总的来说,友元函数是一种在特定情况下提高程序效率的工具,但使用时需要权衡其对封装性的影响。

" 友元函数 " 中 , 需要有一个参数是 类对象的 指针 ;

问题1:下面的代码会输出什么?

void main()
{A a1(1);B b1(2,3);a1.print();//输出啥?1b1.print(); //输出啥?3system("pause");
}void main()
{A a1(1);B b1(2,3);A *base1 = NULL;base1 = &a1;base1->print();  //父类  1A *base2 = NULL;base2 = &b1;base2->print();   //父类  2A &base3 = a1;base3.print();   //父类  1A &base4 = b1;base4.print();   // 父类  2system("pause");
}

多态

但是这不是我想要的,我希望的是,可以输出对应类的print()

希望编译器根据实际的对象类型来判断重写函数的调用

如果父类指针指向的是父类对象则调用父类中定义的函数

如果父类指针指向的是子类对象则调用子类中定义的函数

因此就出现了面向对象的多态概念。

多态(Polymorphisn):不同类的对象可以通过同一接口调用,具有不同的行为。例如,如果有一个函数接受车辆类的对象,那么任何车辆的子类对象,如汽车或摩托车,都可以使用该函数,但具体的行为会根据对象的实际类型而有所不同。多态性在C++中都是通过虚函数(Virtual Function)实现的。虚函数就是允许被其子类重新定义的成员函数,用virtual修饰。而子类重新定义父类虚函数的做法,称为“覆盖”或者称为“重写”(override)。

ps:虚函数是在函数前加了virtual的函数;纯虚函数是前面加了virtual,同时函数被=0的函数,纯虚函数不能被调用

C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。简单地说,多态意味着单个函数可以有多个不同的实现。

解决方案:在同名的成员前,加上virtual。

  • C++中通过virtual关键字对多态进行支持

  • 使用virtual声明的函数被重写后即可展现多态特性

改写上面的例子:

#include <iostream>
using namespace std;
class A
{
private:int a;
public:virtual void print(){cout << "a=" << a << endl;}A(int a){this->a = a;}
};
class B : public A
{
private:int b;
public:virtual void print(){cout << "b=" << b << endl;}B(int a, int b) : A(a){this->b = b;}
};void main()
{A a1(1);B b1(2,3);    A *base1 = NULL;base1 = &a1;base1->print();   //1A *base2 = NULL;base2 = &b1;base2->print();   //3A &base3 = a1;base3.print();  //1A &base4 = b1;base4.print();  //  3system("pause");
}

多态是基于虚函数来实现的。多态实现的三大条件:

(1)要有继承

(2)要有虚函数重写(被调用的函数必须是虚函数,且完成了虚函数的重写)

(3)父类指针或引用指向子类对象

#include <iostream>
class Person 
{
public:virtual void BuyTicket(int){        std::cout << "Adult need Full Fare!" << std::endl;}   
};class Child : public Person
{
public:virtual void BuyTicket(int){        std::cout << "Child Free!" << std::endl;}   
};void fun(Person& obj)
{obj.BuyTicket(1);                                                                                                                             
}int main(void)
{Person p;Child c;fun(p);fun(c);return 0;
}

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

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

相关文章

jupyter notebook设置代码自动补全

jupyter notebook设置代码自动补全 Anaconda Prompt窗口执行 pip install jupyter_contrib_nbextensionsjupyter contrib nbextensions install --userpip install jupyter_nbextensions_configuratorjupyter nbextensions_configurator enable --user按如下图片设置 卸载jed…

线上剧本杀小程序:创新玩法下带来的市场活力

近几年来&#xff0c;剧本杀作为一种新型的游戏娱乐模式&#xff0c;深受年轻人的喜欢&#xff0c;成为了当下年轻人娱乐休闲的主要方式之一。剧本杀行业在经历过一段时间的“野蛮生长”后&#xff0c;游戏内容和服务得到的升级发展&#xff0c;游戏的趣味性和体验感也逐渐增强…

C#基础之冒泡排序

排序初探 文章目录 冒泡排序1、概念2、冒泡排序的基本原理3、代码实现思考1 随机数冒泡排序思考2 函数实现排序 冒泡排序 1、概念 将一组无序的记录序列调整为有序的记录序列&#xff08;升、降序&#xff09; 2、冒泡排序的基本原理 两两相邻&#xff0c;不停比较&#x…

Ieetcode——21.合并两个有序链表

21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 合并两个有序链表我们的思路是创建一个新链表&#xff0c;然后遍历已知的两个有序链表&#xff0c;并比较其节点的val值&#xff0c;将小的尾插到新链表中&#xff0c;然后继续遍历&#xff0c;直到将该两个链表…

【STM32】F4使用通用定时器输出可变PWM方法

网上的文章太啰嗦&#xff0c;这里直接开始。 使用的是STM32CubeIDE&#xff0c;HAL。以通用定时器TIM12在 通道2上输出1KHz的PWM为例。 要确定输出的引脚、定时器连接在哪里。 TIM2、3、4、5、12、13、14在APB1上&#xff0c;最大计数频率84M。 TIM1、8、9、10、11在APB2…

使用groovy+spock优雅的进行单测

使用groovyspock优雅的进行单测 1. groovyspock示例1.1 简单示例1.2 增加where块的示例1.3 实际应用的示例 2. 单测相关问题2.1 与SpringBoot融合2.2 单测数据与测试数据隔离2.3 SQL自动转换&#xff08;MySQL -> H2&#xff09; 参考 Groovy是一种基于JVM的动态语言&#x…

Java的逻辑控制和方法的使用介绍

前言 程序的逻辑结构一共有三种&#xff1a;顺序结构、分支结构和循环结构。顺序结构就是按代码的顺序来执行相应的指令。这里主要讲述Java的分支结构和循环结构&#xff0c;由于和C语言是有相似性的&#xff0c;所以这里只会提及不同点和注意要点~~ 注意在C语言中&#xff0c;…

日本软文发稿:成功的关键与应注意之事项

在当今的营销环境中&#xff0c;产品和服务如何被消费者所知&#xff0c;和品牌如何被市场所接受&#xff0c;软文发稿扮演了极其重要的角色。对于希望在日本市场拓展业务的企业来说&#xff0c;了解和熟悉日本的软文发稿尤其关键。 一&#xff0c;优秀的媒体平台 日本拥有众…

「玻尔曾孙」领衔!超辐射原子,重塑全球精准测时——

超辐射原子能够帮助我们以前所未有的精度测量时间。在哥本哈根大学最近的一项研究中&#xff0c;研究人员开发了一种新的测量时间间隔&#xff08;秒&#xff09;的方法&#xff0c;这种方法克服了目前最先进原子钟面临的一些限制。 这一成就有望在多个领域产生深远影响&#x…

代码随想录Day 36|Python|Leetcode|01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集

01背包问题&#xff0c;你该了解这些&#xff01; 46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; (kamacoder.com) 代码随想录 (programmercarl.com) 确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i][j] 表示从下标为[0-i]的物品里…

「笔试刷题」:求最小公倍数

一、题目 输入描述&#xff1a; 输入两个正整数A和B。 输出描述&#xff1a; 输出A和B的最小公倍数。 示例1 输入&#xff1a; 5 7 输出&#xff1a; 35 示例2 输入&#xff1a; 2 4输出&#xff1a; 4二、思路解析 这道题&#xff0c;也是模拟实现这一大类的一题…

Unity 递归实现数字不重复的排列组合

实现 private void Permutation(List<int> num, int leftIndex, List<string> strs) {if (leftIndex < num.Count){for (int rightIndex leftIndex; rightIndex < num.Count; rightIndex){Swap(num, leftIndex, rightIndex);Permutation(num, leftIndex 1…

MySQL基础学习(待整理)

MySQL 简介 学习路径 MySQL 安装 卸载预安装的mariadb rpm -qa | grep mariadb rpm -e --nodeps mariadb-libs安装网络工具 yum -y install net-tools yum -y install libaio下载rpm-bundle.tar安装包&#xff0c;并解压&#xff0c;使用rpm进行安装 rpm -ivh \ mysql-communi…

Meta的AI潮流:创新还是用户体验的噩梦?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

一、交换网络基础

目录 1.交换机的转发行为 2.数据帧的类型 3.ARP地址解析步骤 Hub&#xff1a;物理层设备 交换机&#xff1a;数据链路层设备 1.交换机的转发行为 泛洪&#xff08;Flooding&#xff09;&#xff08;有可能是单播帧&#xff08;未知单播帧&#xff09;&#xff0c;也有可能是…

【算法一则】【动态规划】求二维数组可组成的最大正方形

题目 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内&#xff0c;找到只包含 ‘1’ 的最大正方形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0","0"],["1","0&…

AutoMQ 系统测试体系揭秘

01 前言 Apache Kafka 有着比较完备的自测体系。除了常规的单元测试和集成测试以外&#xff0c;Apache Kafka 还有着 1000 的“系统集成和性能测试”&#xff08;以下简称系统测试&#xff09;。系统测试会拉起一套真实的 Kafka 集群&#xff0c;并模拟用户使用 Kafka 集群的方…

JAVA 中间件之 Mycat2

Mycat2应用与实战教程 1.Mycat2概述 1.1 什么是MyCat 官网&#xff1a; http://mycatone.top/ Mycat 是基于 java 语言编写的数据库中间件&#xff0c;是一个实现了 MySQL 协议的服务器&#xff0c;前端用户可以把它看作是一个数据库代理&#xff0c;用 MySQL 客户端工具和…

HEVC/H.265视频编解码学习笔记–框架及块划分关系

前言 由于本人在学习视频的过程中&#xff0c;觉得分块单元太多搞不清楚其关系&#xff0c;因此本文着重记录这些分块单元的概念以及关联。 一、框架 视频为一帧一帧的图像&#xff0c;其编码的主要核心是压缩空间以及时间上的冗余。因此&#xff0c;视频编码有帧内预测和帧间…

Linux 进程概念和状态

目录 一、冯诺依曼体系结构 二、操作系统 1.概念 2.理解操作系统的管理 硬件和管理 为什么要有操作系统 三、进程的概念 PCB&#xff1a; 进程的删除和子进程的创建 删除 创建子进程 四、进程的状态 七种状态&#xff1a; 实验查看部分状态&#xff1a; R&#x…