指针和引用是在使用中经常弄混淆的两个概念。
引用(reference)为对象起了另外一个名字,用符号&表示。 &name,例如:
int i=1024;
int &ref=i;
一般在初始化变量时,初始值会被拷贝到新创建的对象中,然而定义引用时,程序把引用和它的初始值绑定(bind)在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。
ref=2; //即 i=2;
int &ref2=ref; //ref2 绑定到了那个与ref绑定的对象上,即i上
引用并非对象,因此,不能定义引用的引用。引用只能绑定到对象上,不能与字面值绑定
int &ref3=1024; //error
指针:
指针与引用的区别:其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向不同的对象;其二,指针无须在定义时赋值。
double *ptr; //ptr 是指向double型对象的指针
指针的值是某个对象的地址
double val=1.0;
double *pval=&val;
利用指针访问对象要用解引用符
cout<<*pval; //指针解引用就是所指向的对象
*pval=2.0; //val的值被改变了,指针pval并没有变
void * 是一种特殊的指针类型,可用于存放任意对象的地址。但不能直接操作void* 指针所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。
指向指针的指针
int i=1024;
int *pi=&i;
int **ppi=π
指向指针的引用
int i=42;
int *p;
int *&r=p; //r 是一个对指针p的引用
r=&i; //赋值改变的是左边的对象,这里r是p的另一个名字,所以给r 赋值就是令p指向i
*r=0; //解引用r得到i,也就是p所指向的对象,将i的值改为0
理解r的类型,最好的办法是从右向左阅读r的定义。&表示r是一个引用,左边的部分是用以确定r引用的类型到底是什么。* 说明r引用的是一个指针,int 说明r引用的是一个int 指针
const
因为const对象一旦创建后其值就不能再改变,所以const对象必须初始化。
在多个文件之间共享const对象:file1: extern const int bufSize=1024; file2 :extern const int bufSize;
const 的引用
const int ci=1024;
cont int &r1=ci; //fine
int &r2=ci; //error
如果对r2 的初始化正确,则可以通过r2来改变ci的值,这跟ci是const int类型 不能改变是冲突的,所以r2语句是错的
int i=42;
int &r1=i; //fine
const int &r2=i; //fine
(注:引用的初始值必须是一个对象,但const 的引用可以是字面值。)
const int &r3=2; //fine
int &ref=10; //error
const 的指针(指向const对象的指针)
同样的,过一个对象是const,则只能使用指向常量的指针;普通指针会尝试修改所指向对象的值
const double p=3.14;
const double * cptr=&p; // fine
double *ptr=&p; //err
const 指针(常量指针)
常量指针:一旦初始化完成,则存放在指针中的那个地址(指针本身的值)不再改变了
int i=10;
int *const ptr=&i; //ptr 一直指向i
const double pi=3.14;
const double * const ptr2=π //ptr2 是一个指向常量对象的常量指针