突破编程_C++_面试(基础知识(7))

面试题16:什么是引用,它与指针有什么区别

引用是变量的别名。对于变量名而言,C++ 实际上对其是不作存储的,在汇编以后不会出现变量名,变量名作用只是用于方便编译器成汇编代码,是给编译器看的,同时也是方便人编写与阅读代码。作为变量名的别名,引用自然也不会在内存中存储,它只是提供了另一种访问已分配内存的方式。另外,引用也并没有自己的内存地址,即使对引用进行取地址操作,返回来的结果也是原变量地址,如下为样例代码:

#include <iostream>  int main() {int val = 1;int& refVal = val;printf("val address = %p\n", &val);printf("refVal address = %p\n", &refVal);return 0;
}

上面代码输出为:

val address = 00000025324FF724
refVal address = 00000025324FF724

从上面的输出可以看到,引用指向的地址(00000025324FF724)就是原变量的地址(00000025324FF724),因此,对引用的任何操作实际上修改的就是原有变量
引用与指针的区别如下
(1)基本概念
引用是变量的别名,是一个已经存在的变量的另一个名字,不占用存储空间。一旦引用被定义并初始化,就不能被重新指向另一个变量。引用总是指向在初始化时被指定的变量,直到该引用和变量都超出作用域。
指针是一个变量,占用存储空间( 32 位平台编译是 4 个字节, 64 位位平台编译是 8 个字节),其值为另一个变量的地址。非 const 的指针可以重新指向另一个变量,即可以改变指针的值,使其指向另一个地址。
(2)访问所指向的变量
使用引用就像使用它所引用的变量一样。例如:int val=1; int& valRef=val; valRef=2;, 该段代码将 val 的值由 1 修改为 2。
使用指针访问其指向的变量需要使用解引用操作符(*)。例如:int val=1; int* prt=&val; *prt=2; , 该段代码将 val 的值由 1 修改为 2。
(3)初始值
引用在定义时必须要同时初始化指向有效的变量,没有空引用的概念。
指针可以是空( nullptr ),指向不确定的内存,或者指向已经被释放的内存。
(4)运算
引用没有自己的地址,不可以进行指针算术。
指针有自己的地址和值,可以进行指针算术(如递增、递减、比较等)。
(5)用途
引用通常用于函数参数和函数返回值,以确保传递的是变量的别名而非副本,从而可以避免值拷贝的过程并且能够修改实际参数的值。
指针除了能够用于函数参数和函数返回值,还可以用于动态内存分配、构建数据结构(如链表、树、图等)以及以函数指针的形式用于回调等过程。
(6)安全性
引用总是指向有效的对象,并且不能被重新指向。所以其类型是固定的,更为安全。
指针可以强制类型转换、可以为空、可以指向无效的地址,所以在使用不当的情况下容易引起程序崩溃。

面试题17:什么是 const 引用,其用途是什么

const 引用指的是对常量的引用,也就是说,不可以通过该引用修改其指向变量的值。其语法形式如下 :

const 类型名& 引用名 = 被引用的常量值或变量;

const 引用有多个重要的用途:
(1)保护数据不被修改:最基本的作用是防止不小心修改数据的值。当你不希望一个变量在函数中被修改时,可以使用 const 引用来传递这个变量。
(2)函数参数传递:在函数形参中使用 const 引用,可以确保在函数内部不会修改实参的值。同时,由于引用避免了数据的拷贝,因此在传递大型数据结构时,使用 const 引用可以提高效率。
(3)增加代码的可读性和安全性:使用 const 引用可以明确地告诉其他阅读代码的人,这个数据是不应该被修改的,从而增加代码的可读性和安全性。
(4)扩展函数的应用范围:使用 const 引用作为函数参数,可以使得函数既能接受常量也能接受非常量作为参数,从而扩展了函数的应用范围。例如:

void printStr(const string& str)
{printf("%s\n", str.c_str());
}
int main()
{printStr("hello");			//正确:这种场景下使用 const 引用可以方便的直接以常量字符串作为入参。return 0;
}

面试题18:当一个对象通过引用传递给函数时,会不会调用拷贝构造函数

当一个对象通过引用传递给函数时,不会调用拷贝构造函数。这是因为引用只是对象的别名,而不是对象的副本。所以引用作为函数参数可以提高程序性能:避免了值传递时无谓的数据拷贝过程,特别是对于大型对象或数据结构来说效果更为显著。同时,引用传递还允许函数修改其参数对象的状态,因为函数操作的是原始对象而不是其副本。

面试题19:如何使用右值引用与 move 来优化性能

右值引用与 move 的配合使用可以将资源(如动态分配的内存)从一个对象转移到另一个对象,而不用进行深拷贝。这个移动过程是通过右值引用、移动构造函数以及移动赋值运算符来实现的。
move 的本质是将左值强制转换为右值引用,避免拷贝带来的性能损失,该函数对具有移动构造函数的类类型有效,但是对于一些基本类型(比如 int 、 float 等)使用时,仍然会发生拷贝( C++ 中所有容器都支持 move 操作)。
移动构造函数与移动赋值函数(重载 operator= 实现)都接受一个右值引用作为参数,并从该参数中移动资源(而非复制资源)。从而是将资源的所有权(如动态内存)从源对象转移到目标对象。
如下是一个使用 move 、移动构造函数以及移动赋值运算提高程序性能的实现过程:

#include <iostream>  using namespace std;class A
{
public:A(){printf("execute constructor function\n");m_val = new int(0);}A(A&& a) noexcept		//移动构造函数 {if (this != &a) {	// 防止自赋值  printf("execute move constructor function\n");m_val = a.getVal();	//内存转移a.initVal();	//源对象的内存做 nullptr 处理,防止其在析构时出现二次释放内存的行为}}A& operator=(A&& a) noexcept		//移动赋值函数 {if (this != &a) // 防止自赋值  {printf("execute operator=() function\n");m_val = a.getVal();	//内存转移a.initVal();	//源对象的内存做 nullptr 处理,防止其在析构时出现二次释放内存的行为}return *this;}~A(){printf("execute destructor function\n");if (nullptr != m_val){delete m_val;m_val = nullptr;}}public:int* getVal() const{return m_val;}void initVal(){m_val = nullptr;}private:int* m_val = nullptr;
};int main()
{A a1;A a2(move(a1));		//调用移动构造函数A a3;A a4;a4 = move(a3);		//调用移动赋值函数,注意:如果写成 A a4 = move(a3); 依然会调用移动构造运算符return 0;
}

上面代码输出为:

execute constructor function
execute move constructor function
execute constructor function
execute constructor function
execute operator=() function
execute destructor function
execute destructor function
execute destructor function
execute destructor function

上面代码中的移动构造函数以及移动赋值函数实现了将堆上的内存 m_val 转移到目标对象的功能。

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

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

相关文章

LeetCode、17. 电话号码的字母组合【中等,dfs回溯】

文章目录 前言LeetCode、17. 电话号码的字母组合【中等&#xff0c;dfs回溯】题目与类型思路递归回溯优化&#xff1a;StringBuilder来回溯补充代码&#xff1a;2024.1.31&#xff08;简化&#xff09; 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博…

C++类和对象:运算符重载

左移运算符重载&#xff1a; class Person {friend ostream& operator<<(ostream& cout, Person& p); public:Person();~Person();static int m_age;void showperson() const{cout << this->m << endl;}int m_A;int m_B;Person operator(Per…

docker部署docker运维工具

简介 主要功能:管理容器,管理镜像,管理容器网络 安装 拉取镜像 docker pull joinsunsoft/docker.ui:1.0.1 启动容器 docker run -d --name docker.ui --restart always -v /var/run/docker.sock:/var/run/docker.sock -p 10039:8999 joinsunsoft/docker.ui:1.0.1 使用 打…

基于鲸鱼优化的knn分类特征选择算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 鲸鱼优化算法&#xff08;WOA&#xff09; 4.1.1 包围猎物 4.1.2 螺旋式搜索 4.1.3 更新策略 4.2 K近邻&#xff08;KNN&#xff09;分类器 4.3 基于WOA的KNN分类特征选择算法 5.完…

将Juniper虚拟防火墙vSRX导入EVE-NG

正文共&#xff1a;555 字 8 图&#xff0c;预估阅读时间&#xff1a;1 分钟 前面我们已经简单介绍了如何导入vSRX的VMware镜像到Workstation&#xff08;Juniper虚拟防火墙vSRX部署初体验&#xff09;&#xff0c;如何导入ESXi并简单操作WEB配置&#xff08;将Juniper虚拟防火…

2.2 反序数

描述 设N是一个四位数&#xff0c;它的9倍恰好是其反序数&#xff08;例如&#xff1a;1234的反序数是4321&#xff09; 求N的值 int main() {for(int i 1;i < 10;i)for(int j 0;j < 10;j)for(int k 0;k < 10;k)for(int l 1;l < 10;l){if((i*1000j*100k*10l)*…

【计算机网络基础篇】学习笔记系列之一《TCP/IP 网络模型》

文章目录 1、问题提出2&#xff0c;网络协议是分层的3&#xff0c;应用层4&#xff0c;传输层5&#xff0c;网络层6&#xff0c;网络接口层7&#xff0c;总结 1、问题提出 为什么要有 TCP/IP 网络模型&#xff1f; 不同设备上的进程间通信需要通过一套通用的网络协议进行网络通…

第二证券:北向资金连续第五日净流入,茅台、工行、五粮液等获加仓

沪指低收险守2700点关口&#xff0c;北向资金接连5日净流入。 2月5日&#xff0c;A股三大股指团体低开&#xff0c;三大股指均创阶段性新低后反弹&#xff0c;创业板指午后首先翻红且一度涨超3%&#xff0c;深成指和沪指也相继转涨。但商场做多情绪欠安&#xff0c;沪深股指重…

opensatck中windows虚拟机CPU核数显示异常问题处理

文章目录 一、问题描述二、元数据信息三、以32核的实例模版为例3.1 单槽位32核3.2 双槽位32核 总结 一、问题描述 openstack创建windows虚拟机的时候&#xff0c;使用普通的实例模版会出现CPU数量和实例模版不一致的问题。需要定制元数据才可以正常显示。 帖子&#xff1a;htt…

米贸搜|关于Facebook广告受限:在这些情况下,Meta会限制广告主的广告能力!

如果你被限制了投放广告&#xff0c;那么你会在Facebook上收到通知。 除了审查广告之外&#xff0c;Meta还监控和调查广告主在Meta技术上的行为&#xff0c;在某些情况下&#xff0c;Meta可能会对广告主施加限制&#xff0c;限制广告主的广告能力&#xff0c;这些限制旨在帮助保…

ChatGPT高效提问—prompt基础

ChatGPT高效提问—prompt基础 ​ 设计一个好的prompt对于获取理想的生成结果至关重要。通过选择合适的关键词、提供明确的上下文、设置特定的约束条件&#xff0c;可以引导模型生成符合预期的回复。例如&#xff0c;在对话中&#xff0c;可以使用明确的问题或陈述引导模型生成…

macbookpro和macbookair的区别?cleanmymac 怎么清理mac空间

苹果mac air和pro区别有&#xff1a;1、air采用了轻薄的设计&#xff0c;重量相对较轻&#xff0c;便于携带&#xff0c;而pro更加注重性能&#xff0c;所以比较重&#xff1b;2、air通常搭载较低功耗的处理器内存和存储容量相对较小&#xff0c;而pro配备了更强大的处理器、更…

基于Vue2用keydown、keyup事件实现长按键盘任意键(或组合键)3秒触发自定义事件(以F1键为例)

核心代码 <template></template> <script> export default {created() {//监听长按快捷键addEventListener("keydown", this.keydown);addEventListener("keyup", this.keyup);},destroyed(d) {//移除长按快捷键removeEventListener(&…

外汇天眼:外汇中的“直接套汇”是指什么?

外汇中的直接套汇又称地点套汇和两角套汇&#xff0c;由于两间汇率高低不同&#xff0c;同时在两个市场上买贱卖贵&#xff0c;从中赚取汇率差额。 例如&#xff1a;英镑的价格在伦敦较贵&#xff0c;或者说英镑在纽约就较便宜&#xff0c;而美元的价值在伦敦较便宜&#xff0c…

硬核:C++实现一个简单的图形用户界面(GUI),包括按钮、文本框和标签等控件

使用Qt库实现简单GUI的示例&#xff1a; #include <QtWidgets>int main(int argc, char** argv) {QApplication app(argc, argv);// 创建一个窗口QWidget window;// 创建一个标签控件QLabel* label new QLabel("Hello World", &window);// 创建一个文本框…

计算机毕业设计 | SpringBoot大型旅游网站 旅行后台管理系统(附源码)

1&#xff0c; 概述 1.1 项目背景 随着互联网技术的快速发展和普及&#xff0c;旅游行业逐渐转向线上&#xff0c;越来越多的游客选择在线预订旅游产品。传统的线下旅行社模式已不能满足市场需求&#xff0c;因此&#xff0c;开发一个高效、便捷的旅游网站成为行业的迫切需求…

算法-2-异或运算

按位异或&#xff1a;相同为0&#xff0c;不同为1 异或运算性质 1&#xff09;异或运算就是无进位相加&#xff08;ab写二进制形式每位相加时不进位&#xff09; 2&#xff09;异或运算满足交换律、结合律&#xff0c;也就是同一批数字&#xff0c;不管异或顺序是什么&#…

【Spring连载】使用Spring Data访问Redis(七)----Hash Mapping

【Spring连载】使用Spring Data访问Redis&#xff08;七&#xff09;----Hash Mapping 一、Hash Mappers二、Jackson2HashMapper 你可以使用Redis中的各种数据结构来存储数据。Jackson2JsonRedisSerializer可以转换JSON格式的对象。理想情况下&#xff0c;通过使用plain键&…

Stable Diffusion 模型下载:majicMIX lux 麦橘辉耀 - V3

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 非常推荐的一个非常绚丽的科幻、梦幻、玄幻般的大模型&#xff0c;由国人“Merjic”发布&#xff0c;下载量颇高。这个模型风格炸裂&#xff0c;远距离脸部需要inp…

071:vue中过滤器filters的使用方法(图文示例)

第071个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使用&#xff0c;computed&a…