当前位置: 首页 > news >正文

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 字节)。
  • 动态多态在调用虚函数时需要通过虚表查找函数地址,这比直接调用非虚函数稍慢。但是这种开销通常是可以接受的,特别是在需要多态的场景中。

🌺🌺🌺撒花!

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

在这里插入图片描述

相关文章:

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

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (2)题目参考答案封装继承多态虚函数底…...

Nginx 常用命令和部署详解及案例示范

一、Nginx常用命令 1.1 启动 Nginx 要启动 Nginx 服务&#xff0c;可以使用以下命令&#xff1a; sudo systemctl start nginx1.2 停止 Nginx 如果需要停止 Nginx 服务&#xff0c;可以使用以下命令&#xff1a; sudo systemctl stop nginx1.3 重启 Nginx 在修改了 Nginx…...

GO大模型应用开发框架-

Eino 旨在提供基于 Golang 语言的终极大模型应用开发框架。 它从开源社区中的诸多优秀 LLM 应用开发框架&#xff0c;如 LangChain 和 LlamaIndex 等获取灵感&#xff0c;同时借鉴前沿研究成果与实际应用&#xff0c;提供了一个强调简洁性、可扩展性、可靠性与有效性&#xff0…...

保姆级!springboot访问Ollama API并调用DeepSeek模型 Api

要在springboot中访问Ollama API并调用DeepSeek模型,你需要遵循以下步骤。首先,确保你有一个有效的Ollama服务器实例运行中,并且DeepSeek模型已经被加载。 可以参考我的这篇博客 保姆级!使用Ollama本地部署DeepSeek-R1大模型 并java通过api 调用 使用Spring Boot + Sprin…...

力扣hot100 ——搜索二维矩阵 || m+n复杂度优化解法

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 解题思路&#xff1a; 借助行和列有序特性&#xff0c;不断按行或者列缩小范围&#xff1b;途中数字表示每…...

娱乐使用,可以生成转账、图片、聊天等对话内容

软件介绍 今天要给大家介绍一款由吾爱大佬 lifeixue 开发的趣味软件。它的玩法超丰富&#xff0c;能够生成各式各样的角色&#xff0c;支持文字聊天、发红包、转账、发语音以及分享图片等多种互动形式&#xff0c;不过在分享前得着重提醒&#xff0c;此软件仅供娱乐&#xff0…...

【PyQt5】python可视化开发:PyQt5介绍,开发环境搭建快速入门

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

使用 FFmpeg 剪辑视频指南

FFmpeg 是一个功能强大的多媒体处理工具&#xff0c;可以进行视频和音频的剪辑、合并、转码等操作。本文将详细介绍如何使用 FFmpeg 进行视频剪辑&#xff0c;并通过实例帮助你快速掌握剪辑技巧。我们会从最基础的剪切功能讲起&#xff0c;再延伸到一些高级操作&#xff0c;如指…...

AWS云从业者认证题库 AWS Cloud Practitioner

题库持续更新&#xff0c;上方二维码查看完整题库&#xff01; 在分担责任模型下&#xff0c;客户对以下哪项负责? A&#xff1a;确保在使用后擦除磁盘驱动器 B&#xff1a;确保在硬件设备上更新固件 C&#xff1a;确保静态数据已加密 D&#xff1a;确保网线为六类或更高类…...

高性能内存对象缓存Memcached详细实验操作

目录 前提准备&#xff1a; cache1&#xff0c;2&#xff1a; 客户端cache-api&#xff08;一定得是LAMP环境&#xff09; memcache实现主主复制以及高可用(基于以上完成) cache1,2: memcachekeepalived(基于以上完成) cache1,2: 前提准备&#xff1a; 1. 准备三台cent…...

【C++复习专题】—— 类和对象,包含类的引入、访问限定符、类的6个默认成员函数等

1.类的定义 class classname {//类体&#xff1a;由成员函数和成员变量组成 }; class为定义类的关键字&#xff0c;classname为类的名字&#xff0c;{}中为类的主体。 类体中的内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量&#xff1b;类中的函数称为类的方…...

Three.js 快速入门教程【一】开启你的 3D Web 开发之旅

系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…...

Windows 图形显示驱动开发-CPU 内存调节和64KB 页面支持

对于 32 位 OS 离散图形处理单元 (GPU) 不支持可调整大小的 BAR&#xff0c;或者当调整帧缓冲区 BAR 的大小失败时&#xff0c;Windows 显示驱动程序模型 (WDDM) v2 将提供一种替代机制&#xff0c;通过该机制可以有效地访问离散 GPU VRAM。 对于支持可编程 BAR 地址空间的 GPU…...

PLC通信交互系统技术分享

目录 0、前言 1、模块划分 2、状态机 3、通信层增强 4、异常处理机制 5、核心代码 关键状态处理示例 6、部署与测试方案 1. 环境要求 2. 性能测试指标 0、前言 这是一个C程序&#xff0c;用于与西门子PLC进行通信&#xff0c;处理SN码、拍照信号、检测结果等流程。代码…...

ceph HEALTH_WARN clock skew detected on mon.f, mon.o, mon.p, mon.q

问题 ceph health detail[WRN] MON_CLOCK_SKEW: clock skew detected on mon.f, mon.o, mon.p, mon.qmon.f clock skew 0.243128s > max 0.05s (latency 0.000836159s)mon.o clock skew 16.249s > max 0.05s (latency 0<...

Git命令行入门

诸神缄默不语-个人CSDN博文目录 之前写过一篇VSCode Git的博文&#xff1a;VSCode上的Git使用手记&#xff08;持续更新ing…&#xff09; 现在随着开发经历增加&#xff0c;感觉用到命令行之类复杂功能的机会越来越多了&#xff0c;所以我专门再写一篇Git命令行的文章。 G…...

pdf-extract-kit paddle paddleocr pdf2markdown.py(效果不佳)

GitHub - opendatalab/PDF-Extract-Kit: A Comprehensive Toolkit for High-Quality PDF Content Extraction https://github.com/opendatalab/PDF-Extract-Kit pdf2markdown.py 运行遇到的问题&#xff1a; 错误&#xff1a; -------------------------------------- C Tra…...

Android 10.0 移除wifi功能及相关菜单

介绍 客户的机器没有wifi功能&#xff0c;所以需要删除wifi相关的菜单&#xff0c;主要有设置-网络和互联网-WLAN,长按桌面设置弹出的WALN快捷方式&#xff0c;长按桌面-微件-设置-WLAN。 修改 Android10 上直接将config_show_wifi_settings改为false,这样wifi菜单的入口就隐…...

什么是Dubbo?Dubbo框架知识点,面试题总结

本篇包含什么是Dubbo&#xff0c;Dubbo的实现原理&#xff0c;节点角色说明&#xff0c;调用关系说明&#xff0c;在实际开发的场景中应该如何选择RPC框架&#xff0c;Dubbo的核心架构&#xff0c;Dubbo的整体架构设计及分层。 主页还有其他的面试资料&#xff0c;有需要的可以…...

Django+Vue3全栈开发实战:从零搭建博客系统

文章目录 1. 开发环境准备2. 创建Django项目与配置3. 设计数据模型与API4. 使用DRF创建RESTful API5. 创建Vue3项目与配置6. 前端页面开发与组件设计7. 前后端交互与Axios集成8. 项目优化与调试9. 部署上线10. 总结与扩展10.1 项目总结10.1.1 技术栈回顾10.1.2 项目亮点 10.2 扩…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...