记录一些面试遇到的问题

重载和重写的区别

重载是overload,覆盖是override
在这里插入图片描述
重载属于编译时多态,覆盖属于运行时多态

运行时多态和编译时多态

运行时多态指的是在运行的时候才知道要调用哪一个函数,编译时多态是指在编译的时候就知道调用哪一个函数。

运行时多态

可以使得父类指针调用子类函数,当然子类指针也可以调用父类函数

#include <iostream>class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() override { std::cout << "Derived class" << std::endl; }
};int main() {Base* ptr;Derived obj;ptr = &obj;ptr->show();  // 调用 Derived::show(),发生运行时多态
}

by the way,如果代码不慎写为了这样,编译器也不会报错,而是友善提示:
函数 ‘show’ 从类 ‘Base’ 中隐藏了一个非虚拟函数

#include <iostream>class Base {
public:void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() { std::cout << "Derived class" << std::endl; }
};int main() {Base* ptr;Derived obj;ptr = &obj;ptr->show();  // 调用 Derived::show(),发生运行时多态
}

因为在C++ 规定,如果子类定义了与基类同名的函数,则基类中的所有同名函数都会被隐藏(即使参数列表不同)。
那如果有一个需求,首先满足Derived类继承了Base,同时有自己的show函数(参数列表和Base不一样,因此单纯的override是不行的),可以在Derived类里添加一句using Base::show;即可。

class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:using Base::show;void show(int a)  { std::cout << "Derived class" <<a<< std::endl; }
};int main() {Derived* ptr; //注意这里变为了Derived*Derived obj;ptr = &obj;ptr->show();ptr->show(1);
}

如果有对多态学术不精,只记得在虚函数的加持下可以使得父类指针访问子类函数,而将上述代码写为了

    Base* ptr; Derived obj;ptr = &obj;ptr->show();ptr->show(1);

代码是不会通过检查的,因为父类指针可以调用子类的函数,但前提是 这个函数必须在父类中声明为 virtual,这样才能实现运行时多态(动态绑定)。
虽然我们在父类里有show()这个函数,但show(int) 不是 Base 类的虚函数,所以 Base* 看不到 Derived 里的 show(int),导致编译错误。

编译时多态

特点:

  1. 同一作用域内,多个函数同名但参数列表不同(参数个数或类型不同)。
  2. 编译时根据函数调用的参数选择具体的函数(编译器做“名字修饰(Name Mangling)”处理)。
  3. 不会引发运行时开销,函数的匹配完全在编译阶段完成。

继承

公有继承
class Base {
public:int a;
protected:int b;private:int c;
};class Derived : public Base {void print(){cout<<b;}
};int main() {Derived* ptr;Derived obj;ptr = &obj;cout << ptr->a;
}

基类的 public 变成 public,protected 变成 protected,private 仍然是 private。

保护继承

在这里插入图片描述基类的 public 和 protected 变成 protected,private 不可访问。

私有继承

private(私有继承):基类的 public 和 protected 变成 private,private 不可访问。

多继承下的菱形继承

sizeof

虚函数的size

在这里插入图片描述
输出的结果为:
在这里插入图片描述
这是因为虚函数引入了虚表,因此需要额外存储一个虚表指针,64位系统下size = 8B。
如果再加上一个int,则为16(需要做到对齐,因此还补了4B)
在这里插入图片描述
多继承的情况下:
输出结果为16,因为继承了A和B,因为有两个虚指针
在这里插入图片描述

普通函数的size

普通函数size = 1

struct的size

struct也要遵循内存对齐,对齐原则是结构体或类的整体大小必须是其最大对齐数的整数倍(最大成员的对齐值
因此比如

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为char[]里有一个’\0’,因此size是6

指针与引用

先来个很经典的题

void GetMemory1(char* p){p = (char*)malloc(100);
}
void Test1(void){char* str =NULL;GetMemory1(str);strcpy(str,"hello");printf(str);
}int main() {Test1();
}

这样会导致程序直接崩溃,原因是GetMemory1传入的函数是指针。注意,这里进行的是值传递,也就是说,我们传入的是str的复制值,因此在GetMemory1里修改p对外面的str没有一点用处。
那么如何修改呢?只需要将GetMemory的参数改为指针的引用 or 指针的指针即可
指针的引用版

void GetMemory1(char* p){p = (char*)malloc(100);
}
void Test1(void){char* str =NULL;GetMemory1(str);strcpy(str,"hello");printf(str);
}int main() {Test1();
}

指针的指针版:

void GetMemory1(char** p){*p = (char*)malloc(100);
}
void Test1(void){char* str =NULL;GetMemory1(&str);strcpy(str,"hello");printf(str);
}

再来个题目

char* GetMemory2(){char p[] = "hello";return p;
}
void Test2(){char* str = NULL;str = GetMemory2();printf(str);
}

这会导致系统崩溃,因为
char p[] = “hello”; 是一个局部数组,存储在上。
当 GetMemory2() 结束后,p 变量的生命周期结束,它所在的栈内存可能被覆盖或释放。
str = GetMemory2(); 让 str 指向了这块无效的内存。
printf(str); 试图访问这块无效的内存,导致未定义行为(Undefined Behavior),可能程序崩溃。
但如果我们修改为,此时内存被分配到堆上,就不会报错了。注意还需要对应的free

char* p = (char*)malloc(100);

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

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

相关文章

【为什么会有 map、weakmap 类型?】

为什么会有 map、weakmap 类型? 传统对象的局限性催生 Map‌1. 键类型单一性‌2. 有序性与迭代支持‌3. 性能优化场景‌ 内存管理需求催生 WeakMap‌1.弱引用机制‌2. 私有数据存储‌3. 规避循环引用问题‌ 总结 传统对象的局限性催生 Map‌ 1. 键类型单一性‌ 传统对象&…

Django下防御Race Condition

目录 漏洞原因 环境搭建 复现 A.无锁无事务时的竞争攻击 B.无锁有事务时的竞争攻击 防御 A.悲观锁加事务防御 B.乐观锁加事务防御 总结 漏洞原因 Race Condition 发生在多个执行实体&#xff08;如线程、进程&#xff09;同时访问共享资源时&#xff0c;由于执行顺序…

课题推荐——无人机在UWB环境下基于TOA/TDOA/AOA的室内定位与精度对比

随着无人机在工业检测、仓储物流、应急救援等室内场景的广泛应用&#xff0c;高精度室内定位技术成为关键支撑。超宽带&#xff08;UWB&#xff09;技术凭借其高时间分辨率、强抗多径能力等优势&#xff0c;成为室内定位的主流方案。然而&#xff0c;不同的定位方法&#xff08…

c语言笔记 fgets

fgets 是 C语言中的一个标准输入输出函数&#xff0c;用于从输入流&#xff08;如文件、键盘等&#xff09;读取一行字符串。它的名字来源于 "File GeT Sring"&#xff0c;表示从文件中读取字符串。 fgets 的函数原型如下&#xff1a; char *fgets(char *str, int n,…

【含文档+PPT+源码】基于微信小程序的农产品自主供销商城系统

项目介绍 本课程演示的是一款基于微信小程序的农产品自主供销商城系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3…

ReAct论文阅读笔记总结

ReAct&#xff1a;Synergizing Reasoning and Acting in Language Models 背景 最近的研究结果暗示了在自主系统中结合语言推理与交互决策的可能性。 一方面&#xff0c;经过适当Prompt的大型语言模型&#xff08;LLMs&#xff09;已经展示了在算术、常识和符号推理任务中通…

20250306-笔记-精读class CVRPEnv:step(self, selected)

文章目录 前言一、if self.time_step<4:控制时间步的递增判断是否在配送中心特定时间步的操作更新更新当前节点和已选择节点列表更新需求和负载更新访问标记更新负无穷掩码更新步骤状态&#xff0c;将更新后的状态同步到 self.step_state 二、使用步骤总结 前言 class CVRP…

nginx服务器实现上传文件功能_使用nginx-upload-module模块

目录 conf文件内容如下html文件内容如下上传文件功能展示 conf文件内容如下 #user nobody; worker_processes 1;error_log /usr/logs/error.log; #error_log /usr/logs/error.log notice; #error_log /usr/logs/error.log info;#pid /usr/logs/nginx.pid;even…

mapbox进阶,模仿百度,简单实现室内楼层切换

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️fill-extrusion三维填充图层样式1.4 ☘…

String / StringBuffer / StringBuilder 的区别是什么?

String、StringBuffer 和 StringBuilder 都是 Java 中用于处理字符串的类&#xff0c;但它们在多个方面存在区别&#xff0c;以下是详细介绍&#xff1a; 1. 可变性 4. 使用场景 String&#xff1a;String 类是不可变的&#xff0c;一旦创建了一个 String 对象&#xff0c;它的…

为何吹订单?因为特斯拉的销量已遥遥领先,掩耳盗铃之举!

从去年以来&#xff0c;多家新造车企业都经常拿大定、小定的数据来说事&#xff0c;而不是如之前说销量领先&#xff0c;原因就在于他们曾对标的特斯拉在销量方面已远远超越&#xff0c;在销量方面无法与特斯拉比拼&#xff0c;就只好用订单 国内媒体一片宣传特斯拉在中国的销量…

深入掌握Redis:从原理到实践的全方位指南

文章为原创&#xff0c;转载请注明出处——Gavana - 半分之月&#x1f319;。 文章在我的博客中同步更新&#xff0c;也可访问本文链接——深入掌握Redis&#xff1a;从原理到实践的全方位指南 | Gavana 关注AI开发工程师Gavana&#xff0c;带你了解更多实用有趣的AI宝藏✨ 个人…

结构型模式---享元模式

概念 享元模式是一种结构型设计模式&#xff0c;他摒弃了在每个对象中保存所有数据的方式&#xff0c;通过共享多个对象所共有的相同状态&#xff0c;让你能在有限的内存容量中载入更多对象。享元模式将原始类中的数据分为内在状态数据和外在状态数据。 内在状态&#xff1a;就…

【Altium】22.11版本后如何导出Gerber镜像层

1、 文档目标 解决 22.11 版本后如何导出 Gerber 镜像层的问题 2、 问题场景 Gerber 导出旧版本&#xff0c;在 AD 22.11 之前的 Gerber 导出中是存在镜像层的选择。 图 1 软件更新至 AD22.11 及之后版本&#xff0c;在 Gerber 导出设置中无法选择层镜像进行导出。 图 2 3、…

Ubuntu 合上屏幕 不待机 设置

有时候需要Ubuntu的机器合上屏幕的时候也能正常工作&#xff0c;而不是处于待机状态。 需要进行配置文件的设置&#xff0c;并重启即可。 1. 修改配置文件 /etc/systemd/logind.conf sudo vi /etc/systemd/logind.conf 然后输入i&#xff0c;进入插入状态&#xff0c;修改如…

Dockerfile 深入浅出:从基础到进阶全解析

Dockerfile 深入浅出&#xff1a;从基础到进阶全解析 各位同学&#xff0c;大家好&#xff01;欢迎来到今天的 Dockerfile 课程。Docker 技术在当今的软件开发和部署领域可以说是非常热门&#xff0c;而 Dockerfile 作为构建 Docker 镜像的关键文件&#xff0c;掌握它对于我们…

视频录像机视频通道是指什么

视频录像机的视频通道是指摄像机在监控矩阵或硬盘录像机设备上的视频输入的物理位置。 与摄像头数量关系&#xff1a;在视频监控系统中&#xff0c;有多少个摄像头就需要多少路视频通道&#xff0c;通道数量决定了视频录像机可接入摄像头的数量&#xff0c;一般硬盘录像机有4路…

2025-03-06 学习记录--C/C++-PTA 习题6-6 使用函数输出一个整数的逆序数

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 二、代码&#xff08;C语言&#xff09;⭐️ #include <stdio.h>int reverse( int number );int main…

游戏引擎学习第138天

仓库:https://gitee.com/mrxiao_com/2d_game_3 资产&#xff1a;game_hero_test_assets_003.zip 发布 我们的目标是展示游戏运行时的完整过程&#xff0c;从像素渲染到不使用GPU的方式&#xff0c;我们自己编写了渲染器并完成了所有的工作。今天我们开始了一些新的内容&#…

LeetCode hot 100—二叉树的最大深度

题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,n…