文章目录
- 一、const引⽤
- 二、指针和引⽤的关系
- 三、inline关键字
- 四、nullptr
一、const引⽤
- 引⽤⼀个const对象,必须⽤const引⽤。
- const引⽤可以引⽤普通对象,因为对象的
访问权限
在引⽤过程中可以缩⼩
,但是不能放⼤
。 - 权限放大
const int a = 1;
//int& b = a;//报错,权限被放大
const int& b = a;//要用const引用
- 权限缩小
int x = 1;
const int& y = x;
- 普通对象之间不存在权限的放大和缩小,只有
引用
和指针
存在权限的放大和缩小
在有些情况下int& b = a3;a3的结果会被存在一个临时对象中,C++规定临时对象具有常性,所以就触发了权限放⼤,必须要⽤常引⽤才可以。
const int& b = a*3;
const引用可以引用
const对象
,普通对象
,临时对象
二、指针和引⽤的关系
- 引⽤是⼀个变量的
取别名不开空间
,指针是存储
⼀个变量地址
,要开空间
。 - 引⽤在定义时
必须初始化
,指针建议初始化,但是语法上不是必须
的。 - 引⽤在初始化时引⽤⼀个对象后,就
不能再引⽤其他对象
;⽽指针可以在不断地改变指向对象
。 - 引⽤可以
直接访问
指向对象,指针需要解引⽤
才是访问指向对象。 - sizeof中含义不同,引⽤结果为
引⽤类型
的⼤⼩,但指针始终是地址空间所占字节个数
- 指针很容易出现空指针和野指针的问题,引⽤
很少出现
,引⽤使⽤起来相对更安全
⼀些。
三、inline关键字
- ⽤inline修饰的函数叫做内联函数,编译时C++编译器会在调⽤的地⽅展开内联函数,这样调⽤内联函数就
不需要
建⽴栈帧了,就可以提⾼效率
。 - inline适⽤于频繁调⽤的
短⼩函数
,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。 - C语⾔实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不⽅便调试,C++设计了inline⽬的就是替代C的宏函数。
宏
// 正确的宏实现
#define ADD(a, b) ((a) + (b))
// 为什么不能加分号?
如果加了分号,宏替换会将将(a,b)替换成((a)+(b));
这就会多一个分号,使用cout时就会出错
// 为什么要加外⾯的括号?
当出现更高优先级运算符时,不加外面的括号会破坏运算符优先级
// 为什么要加⾥⾯的括号?
如果括号里面是表达式,里面不加括号也可能破坏运算符的优先级
- inline不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。
四、nullptr
NULL实际是⼀个宏,C++中NULL可能被定义为字⾯常量0,或者C中被定义为⽆类型指针(void*)的常量。不论采取何种定义,在使⽤空值的指针时,都不可避免的会遇到⼀些⿇烦,本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。f((void*)NULL);调⽤会报错。
- C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,⽽不能被转换为整数类型。
#include<iostream>
using namespace std;
void f(int x)
{
cout << "f(int x)" << endl;
}
void f(int* ptr)
{
cout << "f(int* ptr)" << endl;
}
int main()
{
f(0);
// 本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。
f(NULL);
f((int*)NULL);
// 编译报错:2 个重载中没有⼀个可以转换所有参数类型
// f((void*)NULL);
f(nullptr);
return 0;
}
以上就是今天要讲的内容,本文仅仅简单介绍了关于C++的基础的使用,谢谢