C++语法与面向对象特性(2)

一.inline函数

1.inline的基本特性

被inline修饰的函数被称为内联函数。inline函数设计的初衷是为了优化宏的功能,编译器会在编译阶段对inline函数进行展开。然而需要注意的是,inline对于编译器而言是一种建议,它通常会展开一些简短的,非递归的函数,遇到较为复杂的函数即使有inline修饰编译器也会忽略展开

2.与宏的不同之处

宏也会在编译时展开,对比宏,inline有什么优势?inline修饰的函数可以调试

有了inline修饰的函数,就不需要再考虑宏中复杂的传参问题了。例如:

#include<iostream>
using namespace std;
// 实现⼀个ADD宏函数的常⻅问题
//#define ADD(int a, int b) return a + b;
//#define ADD(a, b) a + b;
//#define ADD(a, b) (a + b)
// 正确的宏实现
#define ADD(a, b) ((a) + (b))
// 为什么不能加分号?
// 为什么要加外⾯的括号?
// 为什么要加⾥⾯的括号?
int main()
{
int ret = ADD(1, 2);
cout << ADD(1, 2) << endl;
cout << ADD(1, 2)*5 << endl;
int x = 1, y = 2;
ADD(x & y, x | y); // -> (x&y+x|y)
return 0;
}

3.使用的注意事项

通常将inline函数定义与声明都放在头文件中

不建议将inline的声明与定义分文件写,会出现链接错误。因为inline函数展开后会没有函数地址

// F.h
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp
#include "F.h"
void f(int i)
{
cout << i << endl;
} /
/ main.cpp
#include "F.h"
int main()
{
// 链接错误:⽆法解析的外部符号 "void __cdecl f(int)" (?f@@YAXH@Z)
f(10);
return 0;
}

地址丢失的底层机制

  1. 函数地址的产生条件

    • 普通函数:编译器生成函数实体,分配唯一地址,符号表记录强符号。

    • inline函数:

      • 若被展开:无独立函数实体 → 无地址。

      • 若未展开:生成弱符号实体,链接器可丢弃未使用的定义。

  2. 分文件编写的致命缺陷

    • 调用方(main.cpp无法看到函数体 → 编译器必须生成函数调用指令。

    • 定义方(F.cpp)的inline函数可能无实体 → 链接器找不到地址。

二.nullptr

nullptr的出现是为了解决C语言中NULL的二义性。C语言中的NULL实际为一个宏,如下:

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

C++中的NULL会被定义为常量0,或C中会被定义为无类型指针(void*),这在函数调用时会产生歧义

这里通过重载f()作为例子

#include<iostream>
using namespace std;
void f(int x)
{
cout << "f(int x)" << endl;
}void f(int* ptr)
{
cout << "f(int* ptr)" << endl;
}

在调用f()时传入f(NULL)会出现什么情况?

显然这里的调用结果与预期不符。

那么尝试将NULL强转为int*会出现什么情况?

因此我们使用nullptr来规避这样的情况

nullptr是一种特殊类型的字面量,它可以隐式转换为各种类型的指针类型,而无法被转换为整型

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

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

相关文章

Linux中grep命令

Linux 中的 grep 用法详解grep 是 Linux 中强大的文本搜索工具&#xff0c;用于在文件或输入流中查找匹配指定模式的行。其基本语法为&#xff1a;grep [选项] "模式" [文件]核心功能基础搜索在文件中查找包含特定字符串的行&#xff1a;grep "error" log.…

【遥感图像入门】遥感中的“景”是什么意思?

在遥感成像中,“3景城市影像”和“5景城市影像”中的“景”是遥感数据的基本单位,通常指一次成像过程中获取的独立遥感影像块。这一概念的具体含义需结合技术背景和应用场景理解: 一、“景”的技术定义 单次成像的独立覆盖区域 遥感平台(如卫星、飞机)在特定时间和位置对…

Pytorch-07 如何快速把已经有的视觉模型权重扒拉过来为己所用

下载&#xff0c;保存&#xff0c;加载&#xff0c;使用模型权重 在这一节里面我们会过一遍对模型权重的常用操作&#xff0c;比如&#xff1a; 如何下载常用模型的预训练权重如何下载常用模型的无训练权重&#xff08;只下载网络结构&#xff09;如何加载模型权重如何保存权…

C语言零基础第9讲:指针基础

目录 1.内存和地址 2.指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量 2.3 解引用操作符&#xff08;*&#xff09; 2.4 指针变量的大小 3.指针变量类型的意义 3.1 指针的解引用 3.2 指针 - 整数 3.3 void*指针 4.指针运算 4.1 指针…

013 HTTP篇

3.1 HTTP常见面试题 1、HTTP基本概念&#xff1a; 超文本传输协议&#xff1a;在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」HTTP常见的状态码 [[Pasted image 20250705140705.png]]HTTP常见字段 Host 字段&#xff1a;客户…

每日面试题20:spring和spring boot的区别

我曾经写过一道面试题&#xff0c;题目是为什么springboot项目可以直接打包给别人运行&#xff1f;其实这涉及到的就是springboot的特点。今天来简单了解一下springboot和spring的区别&#xff0c; Spring 与 Spring Boot&#xff1a;从“全能框架”到“开箱即用”的进化之路 …

ClickHouse数据迁移

ClickHouse实例是阿里云上的云实例&#xff0c;想同步数据到本地&#xff0c;本地部署有ClickHouse实例&#xff0c;下面为单库单表 源实例&#xff1a;阿里云cc-gs5xxxxxxx.public.clickhouse.ads.aliyuncs.com:8123 目标实例&#xff1a;本地172.16.22.10:8123 1、目标实例建…

sqli-labs-master/Less-41~Less-50

Less-41这一关还是用堆叠注入&#xff0c;这关数字型不需要闭合了。用堆叠的话&#xff0c;我们就不爆信息了。我们直接用堆叠&#xff0c;往进去写一条数据?id-1 union select 1,2,3;insert into users (id,username,password) values(666,zk,180)--看一下插进去了没?id-1 u…

Tiger任务管理系统-10

十是个很好美好的数字&#xff0c;十全十美&#xff0c;确实没让人失望&#xff0c;收获还是很大的。 温习了前端知识&#xff0c;巩固了jQuery&#xff0c;thymeleaf等被忽视的框架&#xff0c;意外将之前的所学所用的知识都连起来了&#xff0c;感觉有点像打通了任督二脉一样…

ora-01658 无法为表空间 users中的段创建initial区

ora-01658 无法为表空间 users中的段创建initial区 参考1 参考2 参考3 参考4 给用户新增表空间 alter tablespace system add datafile D:\APP\ADMINISTRATOR\ORADATA\ORCL\SYSTEM03.DBF size 5G autoextend on next 10M;设置表空间文件自动扩展 ALTER DATABASE DATAFILE /…

lodash的替代品es-toolkit详解

一、es-toolkit简介 es-toolkit 是一款先进的高性能 JavaScript 实用程序库,体积小巧,并支持强类型注释,典型特征包括: 提供各种日常实用函数并采用现代实现,例如: debounce、delay、chunk、sum 和 pick 等 设计充分考虑了性能,在现代 JavaScript 环境中实现了 2-3 倍…

【原创】基于gemini-2.5-flash-preview-05-20多模态模型实现短视频的自动化二创

画面和解说保持一致&#xff0c;这个模型就是NB[16:57:37] [*] 正在从视频中提取帧和时长 (频率: 1.0 帧/秒)... [16:57:55] [] 提取完成。视频时长: 83.40秒, 提取了 84 帧。 [16:57:55] [*] 使用AI供应商: gemini [16:57:55] [*] 正在进行视觉分析... [16:57:55] L-> 正…

数仓架构 数据表建模

数仓架构 主要用来描述 数据加工的实时链路 和 离线链路之间的关系,即 流批 关系; lamda 架构, 是两条路, 实时计算式的, 维护数据的实时性。然后每天经过批计算后, 覆盖实时的计算结果。 保证数据准确性。 kappa架构, 即流批一体了 数据建模 星型模型是数据仓库中最…

vscode调试python脚本时无法进入函数内部的解决方法

只需在launch.json配置文件中添加“justMyCode”:false.

Python day37

浙大疏锦行 python day37. 内容&#xff1a; 保存模型只需要保存模型的参数即可&#xff0c;使用的时候直接构建模型再导入参数即可 # 保存模型参数 torch.save(model.state_dict(), "model_weights.pth")# 加载参数&#xff08;需先定义模型结构&#xff09; mod…

ORACLE进阶操作

1 事务 事务的任务便是使数据库从一种状态变换成为另一种状态&#xff0c;这不同于文件系统&#xff0c;它是数据库所特用的。 所有的数据库中&#xff0c;事务只针对DML&#xff08;增删改)&#xff0c;不针对select select只能查看其他事务提交或回滚的数据&#xff0c;不能查…

Modbus 的一些理解

疑问&#xff1a;&#xff08;使用的是Modbustcp&#xff09;我在 Modbus slave 上面设置了slave地址为1&#xff0c;位置为40001的位置的值为1&#xff0c;40001这个位置上面的值是怎么存储的&#xff0c;存储在哪里的&#xff1f;他们是怎么进行交互的&#xff1f;在Modbus协…

【运动控制框架】WPF运动控制框架源码,可用于激光切割机,雕刻机,分板机,点胶机,插件机等设备,开箱即用

WPF运动控制框架源码&#xff0c;可用于激光切割机&#xff0c;雕刻机&#xff0c;分板机&#xff0c;点胶机&#xff0c;插件机等设备&#xff0c;考虑到各运动控制硬件不同&#xff0c;视觉应用功能&#xff08;应用视觉软件&#xff09;也不同&#xff0c;所以只开发各路径编…

RabbitMQ-日常运维命令

作者介绍&#xff1a;简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。中间件&#xff0c;我给它的定义就是为了实现某系业务功能依赖的软件&#xff0c;包括如下部分:Web服务器代理…

【Linux基础知识系列】第九十篇 - 使用awk进行文本处理

在Linux系统中&#xff0c;文本处理是一个常见的任务&#xff0c;尤其是在处理日志文件、配置文件和数据文件时。awk是一个功能强大的文本处理工具&#xff0c;广泛用于数据提取、分析和格式化。它不仅可以处理简单的文本文件&#xff0c;还可以处理复杂的结构化数据&#xff0…