C/C++ | 每日一练 (2)

💢欢迎来到张胤尘的技术站
💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥

文章目录

  • C/C++ | 每日一练 (2)
    • 题目
    • 参考答案
      • 封装
      • 继承
      • 多态
        • 虚函数
        • 底层实现
          • 单继承
          • 多继承
        • 注意事项

C/C++ | 每日一练 (2)

题目

简述 c++ 面向对象的三大特性。

参考答案

面向对象三大特性:封装、继承、多态。

封装

封装指的是将对象的行为和属性结合成为一个类,并隐藏对象的内部实现细节,仅通过对象的接口(即公开的方法)与外界交互。

  • 隐藏内部实现细节:保护对象的内部状态,防止外部直接访问或修改对象的私有成员。
  • 提供统一的接口:通过公开的方法(如构造函数、成员函数等)对外提供服务,使对象的使用更加安全和方便。

例如:

#include <iostream>class Person
{
private:// 私有成员,外部无法直接访问std::string name;int age;public:// 提供接口访问私有成员void setName(const std::string &newName){name = newName;}void setAge(int newAge){age = newAge;}void display() const{std::cout << name << " is " << age << " years old." << std::endl;}
};

继承

继承是指一个类(派生类或子类)可以继承另一个类(基类或父类)的属性和方法。子类可以扩展或修改父类的功能,而无需重新编写相同的代码,支持代码重用和扩展。继承可以是单继承或多继承(在 c++ 中支持)

继承的主要作用是:

  • 代码复用:减少重复代码,提高开发效率。
  • 拓展功能:派生类可以在继承基类的基础上,添加新的功能或修改现有功能。
#include <iostream>class Animal
{
public:void eat(){std::cout << "animal eat" << std::endl;}
};class Dog : public Animal
{
public:void bark(){std::cout << "dog eat" << std::endl;}
};

多态

多态是指相同的接口在不同的类实例上具有不同的表现形式。多态分为:

  • 编译时多态(函数重载和运算符重载)

  • 运行时多态(通过虚函数实现)。

运行时多态是面向对象编程中最重要的多态形式,它通过虚函数和继承实现。

例如:

#include <iostream>class Shape
{
public:// 定义为虚函数virtual void draw() const{std::cout << "drawing a shape" << std::endl;}
};class Circle : public Shape
{
public:// 重写基类的虚函数void draw() const override{std::cout << "drawing a circle" << std::endl;}
};class Square : public Shape
{
public:// 重写基类的虚函数void draw() const override{std::cout << "drawing a square" << std::endl;}
};int main()
{Shape *s1 = new Circle();Shape *s2 = new Square();s1->draw(); // drawing a circles2->draw(); // drawing a squaredelete s1;delete s2;
}
虚函数

c++ 中,虚函数是实现运行时多态的关键机制。它允许派生类重写继承自基类的成员函数,从而在运行时根据对象的实际类型调用相应的函数实现。

虚函数是在基类中通过关键字 virtual 声明的成员函数。它的作用是让派生类可以覆盖该函数,从而实现多态行为。

#include <iostream>class Base {
public:virtual void display() { std::cout << "Base::display()" << std::endl;}
}

虚函数的主要作用是实现 动态绑定或运行时多态。具体来说:

  • 当通过基类指针或引用调用虚函数时,程序会根据对象的实际类型(派生类类型)来调用对应的函数实现。
  • 如果没有虚函数,调用的将是基类的成员函数,而不是派生类的实现,这种行为称为静态绑定
#include <iostream>class Base {
public:virtual void display() {std::cout << "Base::display()" << std::endl;}
};class Derived : public Base {
public:// 重写基类的虚函数void display() override {std::cout << "Derived::display()" << std::endl;}
};int main() {Base* ptr = new Derived();delete ptr;return 0;
}

在上述代码中,ptr 是基类指针指向子类对象,由于 display() 是虚函数,程序会调用派生类的 display() 的实现。

底层实现

虚函数的实现依赖于虚表(简称 vtable)和虚表指针vptr):

  • 每个包含虚函数的类都有一个虚表(vtable),虚表中存储了该类中所有虚函数的地址。
  • 每个对象在对象头中会隐式地包含一个虚表指针(vptr),指向其所属类的虚表。
  • 当通过基类指针或引用调用虚函数时,程序会通过 vptr 查找虚表,然后在虚表中根据函数索引找到正确的函数地址。
  • 执行函数调用。
单继承

单继承的动态多态结构图如下所示:

在这里插入图片描述

多继承

多继承是 c++ 中的一种继承方式,它允许一个子类从多个基类继承属性和行为。这种继承方式可以提供更大的灵活性,使得派生类能够组合多个基类的特性。但是,多继承也引入了复杂性,尤其是在内存布局、虚函数表、构造和析构顺序等方面。多继承的动态多态结构图如下所示:

#include <iostream>class Base1
{
public:virtual void display(){std::cout << "Base1::display()" << std::endl;}virtual void show(){std::cout << "Base1::show()" << std::endl;}virtual ~Base1(){std::cout << "Base1::~Base1()" << std::endl;}private:int a;int b;
};class Base2
{
public:virtual void cat(){std::cout << "Base2::cat()" << std::endl;}virtual ~Base2(){std::cout << "Base2::~Base2()" << std::endl;}private:int c;
};class Derived : public Base1, public Base2
{
public:// 重写基类的虚函数void display() override{std::cout << "Derived::display()" << std::endl;}void cat() override{std::cout << "Derived::cat()" << std::endl;}~Derived() override {std::cout << "Derived::~Derived" << std::endl;}
private:int d;
};int main() {Base1* ptr1 = new Derived();Base2* ptr2 = new Derived();delete ptr1;delete ptr2;return 0;
}

在这里插入图片描述

注意事项
  • 虚函数必须是成员函数:全局函数或静态成员函数不能声明为虚函数。
  • 派生类的覆盖函数必须与基类的虚函数具有相同的签名(函数名、参数类型和数量)。如果派生类的函数与基类虚函数签名不一致(函数名相同,参数类型和数量不相同),则不会覆盖而是隐藏。
  • 纯虚函数:在基类中,可以将虚函数声明为纯虚函数,即在声明时赋值为 = 0。包含纯虚函数的类称为抽象类,不能实例化对象。
class AbstractClass {
public:virtual void func() = 0;  // 纯虚函数
};
  • 析构函数的虚化:如果基类有虚函数,通常需要将析构函数声明为虚函数,以确保通过基类指针删除派生类对象时,能够正确调用派生类的析构函数。
class Base {
public:virtual ~Base() { cout << "Base destructor" << endl; }
};class Derived : public Base {
public:~Derived() { cout << "Derived destructor" << endl; }
};
  • 虚函数的实现依赖于虚表和虚表指针,因此会带来一定的性能开销;每个对象需要存储一个虚表指针(通常为 4 字节或 8 字节)。
  • 动态多态在调用虚函数时需要通过虚表查找函数地址,这比直接调用非虚函数稍慢。但是这种开销通常是可以接受的,特别是在需要多态的场景中。

🌺🌺🌺撒花!

如果本文对你有帮助,就点关注或者留个👍
如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。

在这里插入图片描述

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

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

相关文章

DeepSeek应用-一秒对书本要点分析并创建思维脑图

2025年开始啦&#xff0c;从DeepSeek的火爆程度来看&#xff0c;今年必须紧盯DS的发展&#xff0c;AI不会淘汰人&#xff0c;AI只会淘汰不会使用的人。从文心一言、豆包、Kimi到DS,基本上从功能上大致相同&#xff0c;但是DeepSeek的开源着实在眼界和格局上更胜一筹&#xff0c…

4、IP查找工具-Angry IP Scanner

在前序文章中&#xff0c;提到了多种IP查找方法&#xff0c;可能回存在不同场景需要使用不同的查找命令&#xff0c;有些不容易记忆&#xff0c;本文将介绍一个比较优秀的IP查找工具&#xff0c;可以应用在连接树莓派或查找IP的其他场景中。供大家参考。 Angry IP Scanner下载…

android 的抓包工具

charles 抓包工具 官网地址 nullCharles Web Debugging Proxy - Official Sitehttps://www.charlesproxy.com/使用手册一定记得看官网 SSL Certificates • Charles Web Debugging Proxy http请求&#xff1a; 1.启动代理&#xff1a; 2.设置设备端口 3.手机连接当前代理 …

Java常用工具类详解

目录 一、Java 中的数学利器&#xff1a;java.lang.Math 类详解 1.常用属性 2.常用方法 ⑴.static int abs(int a) ⑵.static double ceil(double a) ⑶.static double floor(double a) ⑷.static int max(int a, int b) 和 static int min(int a, int b) ⑸.static do…

STM32 低功耗模式

目录 背景 低功耗模式 睡眠模式 进入睡眠模式 退出睡眠模式 停止模式 进入停止模式 退出停止模式 待机模式 进入待机模式 退出待机模式 程序 睡眠模式 休眠模式配置 进入休眠模式 退出睡眠模式 停止模式 停止模式配置 进入停止模式 退出停止模式 待机模式…

uniapp 使用v-html在微信小程序中渲染成rich-text如何显示文本溢出省略

一、问题描述 小伙伴有个需求&#xff0c;想在uniapp开发的微信小程序的一个列表中对内容进行显示溢出显示省略号的控制&#xff1a;当文本超出一行之后&#xff0c;显示…。 经过尝试&#xff0c;无法在v-html所在的节点进行ellipise的控制。 二、解决方案 1.增加函数&…

VMware 17 安装 VMTools(win 7旗舰 X64)

由于在VM 17中安装的 win 7虚拟机没有安装VM Tools 的原因&#xff0c;界面有大黑边&#xff0c;也无法直接拖拽复制粘贴文件&#xff08;但是如果只是要复制文件&#xff0c;最简单的方法还是使用U盘&#xff09;&#xff0c;所以下面开始安装VM Tools 。 若直接选择VM软件中的…

【MySQL】我在广州学Mysql 系列——Mysql 日志管理详解

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天又是新的一周了&#xff0c;又该摆好心态迎接美好的明天了&#xff01;&#xff01;&#xff01;&#x1f606; 本文主要对Mysql数据库中的日志种类以及基本命令进行讨论&#xff01;&#xff01; 回顾&#xff1a;&#x1f4…

python学opencv|读取图像(六十五)使用cv2.boundingRect()函数实现图像轮廓矩形标注

【1】引言 前序学习进程中&#xff0c;已经使用cv2.findContours()函数cv2.drawContours()函数实现图像轮廓识别和标注&#xff0c;这种标注沿着图像的轮廓进行&#xff0c;比较细致。相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;六十四&#xff09;使用…

DeepSeek-V3 技术报告

DeepSeek-V3 Technical Report https://arxiv.org/abs/2412.19437 1. 核心贡献 DeepSeek-V3 是一个拥有 6710 亿参数的大规模混合专家&#xff08;MoE&#xff09;语言模型&#xff0c;每个 token 激活 370 亿参数。 该模型通过创新的架构设计和训练策略&#xff0c;实现了高效…

PCIe7.0信号完整性优化的一些方向

首先考虑过孔stub的影响&#xff0c;分别仿真10mil stub&#xff0c;6mil stub&#xff0c;3mil stub以及无stub四种情况&#xff0c;观察insertion loss/ return loss/TDR Impedance profile、crosstalk四个参数对比情况。 仿真对比结果如下&#xff1a; 其次&#xff0c;考虑…

学习threejs,使用PointLight点光源

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.PointLight 二、&…

30填学习自制操作系统第二天

今天要干什么&#xff1f; 初步了解汇编语言使用汇编重新写个昨天的镜像文件继续开发 一: 什么是电信号&#xff1f; 电脑的处理中心是CPU&#xff0c;即“central process unit”的缩写&#xff0c;翻译成中文就是“中央处理单元”&#xff0c;顾名思义&#xff0c;他就是…

Python的顺序结构和循环结构

文章目录 一、条件语句&#xff08;1&#xff09;条件语句的定义&#xff08;2&#xff09;条件语句的语法&#xff08;a&#xff09;单分支 if&#xff08;b&#xff09;双分支 if-else&#xff08;c&#xff09;多分支 if-elif-elif-...-else &#xff08;3&#xff09;注意事…

金蝶云星空点击按钮实现指定文件下载

文章目录 金蝶云星空点击按钮实现指定文件下载业务需求开发实现 金蝶云星空点击按钮实现指定文件下载 业务需求 点击按钮&#xff0c;下载excel 开发实现 创建表单插件&#xff0c;在按钮点击事件&#xff0c;调用附件下载窗口进行指定路径的指定文件下载 模板存放路径 …

EasyExcel的简单使用

EasyExcel使用 官方文档&#xff1a;关于EasyExcel 1.1EasyExcel相关依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.11</version></dependency> 1.2 写Excel 1.2.1 最…

游戏引擎学习第107天

仓库:https://gitee.com/mrxiao_com/2d_game_2 回顾我们之前停留的位置 在这段内容中&#xff0c;讨论了如何处理游戏中的三维效果&#xff0c;特别是如何处理额外的“Z层”。由于游戏中的艺术资源是位图而不是3D模型&#xff0c;因此实现三维效果变得非常具有挑战性。虽然可…

「vue3-element-admin」基于 TypeScript 的 ECharts 按需引入方案实战 - Vue3 项目打包体积优化 57%

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …

用Python实现图像风格迁移的技术分析

文章目录 一、概要 二、效果预览 三、整体架构流程 1. 用户界面(GUI): 2. 图像加载与显示: 3. 风格迁移核心算法: 4. 结果显示与保存: 5. 多线程处理: 四、技术名词解释 1. OpenCV: 2. TensorFlow: 3. VGG19: 4. GUI(图形用户界面): 5. 多线程: 五…

gsoap实现webservice服务

gsoap实现webservice服务 在实现Web服务时&#xff0c;使用gSOAP是一个很好的选择&#xff0c;因为它提供了强大的工具和库来创建SOAP和RESTful服务。gSOAP是一个C和C语言开发的库&#xff0c;它支持SOAP协议的各种版本&#xff0c;包括SOAP 1.1和SOAP 1.2。下面是如何使用gSO…