指针和引用

1. 指针(pointer)

1.1 定义

指针(pointer)本质上是指向(point to)其他对象的对象,其内存中存储的是地址,可以通过解引用操作间接的去访问其指向内存对象(如果指针中存储的是一个有效的地址)

1.2 初始化和赋值

指针无需在定义时初始化,并且可以随时指向其他对象,因此在使用指针前,需要对其进行有效性检查,否则可能会访问无效指针

1.3 指针的值

指针的值有四种可能
1. 指向一个对象
2. 指向紧邻对象所占空间的下一个位置
3. 空指针,即没有指向任何对象
4. 无效指针

1.4 void*

void* 指针可以指向任意类型的对象,但不能直接操作其指向的对象

1.5 const和指针

  1. 指针常量(T* const p)是一个指针类型的常量,在定义时必须初始化,并且该指针在初始化指向某一对象后不能在指向其他对象了,但可以通过指针去改变其所指向的对象的值
  2. 常量指针(const T* p)是一个指向“常量对象”的指针,即不能通过该指针对改变其指向对象的值,但该指针可以指向其他对象。可以让一个常量指针指向一个非常量对象,但常量对象只能由常量对象指向

1.6 类型匹配

指针的类型必须与其所指向对象的类型严格匹配,但有两个例外:

  • 常量指针(const T*)可以用任意表达式进行赋值,只要改表达式的旳值能转化成该指针的类型(T)即可,如非常量对象、字面值
int i = 24;
const int* p1 = i; // ok
const int* p2 = 0x24; // ok 指向一个地址为0x24的int型临时对象上
int* p3 = 24  // error

const char* p4 = "hello world" // ok 指向一个内容为"hello world"的char* 型临时对象上
char* p4 = "hello world"  // error
  • 可以让一个基类指针指向派生类对象
class Base
{
    ...
};

class Derived : pulic Base
{
    ...
}

Base* p = new Derived();

2 引用(reference)

2.1 定义

引用(reference)是其所绑定对象的别名,操作引用相当于直接操作其引用的对象

2.2 初始化和赋值

引用在定义时必须初始化,即将该引用与一个对象绑定,并且该引用在其生命周期内不能在绑定其它对象

2.3 const和引用

  1. 由于引用在其生命周期内只能绑定一个对象,所以其天然具有常量性,所以也没有引用常量这个说法
  2. 常量引用(const T& )是一个对“常量对象”的引用,即不能通过该引用去修改其引用对象的值

2.4 类型匹配

引用的类型必须与其所引用对象的类型严格匹配,但有两个例外:

  • 常量引用(const T&)初始化时可以用任意表达式作为初始值,只要改表达式的旳值能转化成该引用的类型(T)即可,如非常量对象、字面值
int i = 24;
const int& r1 = i; // ok
const int& r2 = 24; // ok 绑定到一个值为24的int型临时对象上
int& r3 = 24  // error

double d = 24.0;
const int& r4 = d // ok 绑定到一个值为24的int型临时对象上
const int& r5 = 24.0 // ok 绑定到一个值为24的int型临时对象上
int& r5 = d  // error
  • 可以将一个派生类的对象绑定到一个基类引用上
class Base
{
    ...
};

class Derived : pulic Base
{
    ...
}

Derived derived;
Base& p = derived;

3. 区别

  1. 引用一个对象的别名;指针是存有其他对象地址的对象
  2. 引用在定义时必须初始化;指针不必
  3. 引用在初始化时绑定一个对象后,在其生命周期内不可以再绑定到其它的对象;指针在其生命周期内可以任意修改其值
  4. 在使用引用前不用对其进行有效性检查;指针必须对进行有效性检查
  5. 不存在引用的引用,即多级引用;存在指针的指针,即多级指针
  6. 不存在引用常量;存在指针常量
  7. 引用和指针的算术运算的意义不同

4. 引用的底层实现

C++标准中没有规定引用是如何实现的,这个工作交给了编译器,然而大多数编译器(VS和GCC)使用了指针常量去实现引用,即引用是指针的语法糖(syntactic sugar),只不过对使用者隐藏了实现细节

The C++ standard is very careful to avoid dictating how a compiler must implement references, but every C++ compiler implements references as pointers. That is, a declaration such as:
int &ri = i;
if it’s not optimized away entirely, allocates the same amount of storage as a pointer, and places the address of i into that storage.

int i = 24;

int &r = i; 
等价于 
int* const r = &i 

r = 25; 
等价于 
*r = 25

5. Reference

  1. https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in

  2. https://www.cnblogs.com/chenhuan001/p/6702934.html

  3. http://blog.youkuaiyun.com/Mind_V/article/details/78619163
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值