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

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.dtcms.com/a/319677.html

相关文章:

  • PyTorch如何实现婴儿哭声检测和识别
  • 目标检测数据集 - 自动驾驶场景道路异常检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • 接口自动化-pytest
  • OpenAI 开源模型 gpt-oss 正式上线微软 Foundry 平台
  • 网络可视,运维无忧:分钟级定位,告别盲目扩容
  • 从零开始构建情绪可视化日记平台 - React + TypeScript + Vite
  • CPTS Remote 复现
  • Redisson中的分布式锁
  • 自动化办公革命:3小时完成8小时工作量
  • 钢卷矫平机科普:把“弯曲的记忆”清零
  • 人工智能与能源:AI 驱动的能源产业变革
  • MCU-基于TC397的双BootLoader设计方案
  • 关于vue2中对接海康摄像头以及直播流rtsp或rtmp,后台ffmpeg转码后通过ws实现
  • 【linux】vmware中ubuntu无法上网
  • 关于 cadence导入原理图出现ERROR(ORCAP-1192)错误 的解决方法
  • 蓝桥杯算法之搜索章 - 3
  • HarmonyOS分布式开发实战:打造跨设备协同应用
  • C 语言主控开发与显控开发能力体系及技术栈详解,STM32、QT、嵌入式、边缘系统显示
  • 【Vite】Vite 构建 React 项目中 Select a variant 配置选择指南:标准版 vs SWC
  • shell脚本while只循环一次,后续循环失效
  • 解码算法:维特比算法(Viterbi)在SMT中的应用
  • 开发避坑指南(20) :MyBatis操作Oracle插入NULL值异常“无效列类型1111“解决方案
  • 金仓KingbaseES逻辑架构,与Oracle/MySQL对比
  • Windows Oracle 11 g dmp数据库恢复笔记
  • 一种基于CEEMDAN-小波阈值联合降噪-快速谱峭度(FSK)/基尼谱Ginigram/Autogram的故障诊断 Matlab
  • 【已解决】-bash: mvn: command not found
  • [Oracle] FLOOR()函数
  • Oracle 12c + Pl/Sql windows系统下表空间创建、迁移,dmp备份导入,数据库字符集更改
  • 7. 什么是事件委托
  • 试用一个用v语言编写的单文件数据库vsql