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)
💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 C/C | 每日一练 (2)题目参考答案封装继承多态虚函数底…...
Nginx 常用命令和部署详解及案例示范
一、Nginx常用命令 1.1 启动 Nginx 要启动 Nginx 服务,可以使用以下命令: sudo systemctl start nginx1.2 停止 Nginx 如果需要停止 Nginx 服务,可以使用以下命令: sudo systemctl stop nginx1.3 重启 Nginx 在修改了 Nginx…...
GO大模型应用开发框架-
Eino 旨在提供基于 Golang 语言的终极大模型应用开发框架。 它从开源社区中的诸多优秀 LLM 应用开发框架,如 LangChain 和 LlamaIndex 等获取灵感,同时借鉴前沿研究成果与实际应用,提供了一个强调简洁性、可扩展性、可靠性与有效性࿰…...
保姆级!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 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 解题思路: 借助行和列有序特性,不断按行或者列缩小范围;途中数字表示每…...
娱乐使用,可以生成转账、图片、聊天等对话内容
软件介绍 今天要给大家介绍一款由吾爱大佬 lifeixue 开发的趣味软件。它的玩法超丰富,能够生成各式各样的角色,支持文字聊天、发红包、转账、发语音以及分享图片等多种互动形式,不过在分享前得着重提醒,此软件仅供娱乐࿰…...
【PyQt5】python可视化开发:PyQt5介绍,开发环境搭建快速入门
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
使用 FFmpeg 剪辑视频指南
FFmpeg 是一个功能强大的多媒体处理工具,可以进行视频和音频的剪辑、合并、转码等操作。本文将详细介绍如何使用 FFmpeg 进行视频剪辑,并通过实例帮助你快速掌握剪辑技巧。我们会从最基础的剪切功能讲起,再延伸到一些高级操作,如指…...
AWS云从业者认证题库 AWS Cloud Practitioner
题库持续更新,上方二维码查看完整题库! 在分担责任模型下,客户对以下哪项负责? A:确保在使用后擦除磁盘驱动器 B:确保在硬件设备上更新固件 C:确保静态数据已加密 D:确保网线为六类或更高类…...
高性能内存对象缓存Memcached详细实验操作
目录 前提准备: cache1,2: 客户端cache-api(一定得是LAMP环境) memcache实现主主复制以及高可用(基于以上完成) cache1,2: memcachekeepalived(基于以上完成) cache1,2: 前提准备: 1. 准备三台cent…...
【C++复习专题】—— 类和对象,包含类的引入、访问限定符、类的6个默认成员函数等
1.类的定义 class classname {//类体:由成员函数和成员变量组成 }; class为定义类的关键字,classname为类的名字,{}中为类的主体。 类体中的内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方…...
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,或者当调整帧缓冲区 BAR 的大小失败时,Windows 显示驱动程序模型 (WDDM) v2 将提供一种替代机制,通过该机制可以有效地访问离散 GPU VRAM。 对于支持可编程 BAR 地址空间的 GPU…...
PLC通信交互系统技术分享
目录 0、前言 1、模块划分 2、状态机 3、通信层增强 4、异常处理机制 5、核心代码 关键状态处理示例 6、部署与测试方案 1. 环境要求 2. 性能测试指标 0、前言 这是一个C程序,用于与西门子PLC进行通信,处理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的博文:VSCode上的Git使用手记(持续更新ing…) 现在随着开发经历增加,感觉用到命令行之类复杂功能的机会越来越多了,所以我专门再写一篇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 运行遇到的问题: 错误: -------------------------------------- C Tra…...
Android 10.0 移除wifi功能及相关菜单
介绍 客户的机器没有wifi功能,所以需要删除wifi相关的菜单,主要有设置-网络和互联网-WLAN,长按桌面设置弹出的WALN快捷方式,长按桌面-微件-设置-WLAN。 修改 Android10 上直接将config_show_wifi_settings改为false,这样wifi菜单的入口就隐…...
什么是Dubbo?Dubbo框架知识点,面试题总结
本篇包含什么是Dubbo,Dubbo的实现原理,节点角色说明,调用关系说明,在实际开发的场景中应该如何选择RPC框架,Dubbo的核心架构,Dubbo的整体架构设计及分层。 主页还有其他的面试资料,有需要的可以…...
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 扩…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
