void*为“无类型指针”,能够指向任何类型的数据,可是访问数据时必须指明。函数
看下面的小例子:spa
int a = 5; void *p = &a; cout<<*p; //编译错误,'void*' is not a pointer-to-object type cout<<*(int*)p; //ok cout<<*(double*)p; //能够经过编译和运行,可是结果确定是错误的
其实,void* 指针能作的事情颇有限:1.指针比较。2.做为函数传入参数,或返回参数。3.赋给另外一个void* 指针。
指针
不能经过void* 指针来访问它所指的对象(由于咱们不知道对象的类型,而对象类型决定了能够进行哪些操做。),若是想访问它所指的类型,须要显式指出。code
int i = 42; int *p = &i; //指针p指向i int *&r = p; //r是指针p的引用,r是一个指向int类型的指针的引用 *r = 50; //here, i==50, *p == 50
int i = 42; const int &r1 = i; //ok r1 = 100; //error, cause it's const i = 100; cout << r1; //here, r1==100
const引用能够用普通对象来初始化,可是不能经过cont引用来修改该对象。看下面的小例子:对象
double dval = 3.14; const int &r1 = dval; dval = 3.15; cout<<r1; //ri == 3
这里,能够用const引用绑定不是该类型的对象(int r1 = dval;就不能够)。其实这里引用绑定的是一个临时对象。至关于:ip
const int temp = dval; //建立了一个临时对象,为3 const int &r1 = temp; //将引用与临时对象绑定,因此结果输出为3
指针不可能知道它所指向的对象是const对象仍是普通对象,因此它对它所指向的全部对象都当成是const对象。指向const对象的指针能够被认为是“它们认为它们本身指向const对象的指针”。it
不能经过该指针修改对象的值,不过能够改变该指针指向的对象。pip
const double pi = 3.14; double *ptr = π //error,不能用普通指针存储const对象地址 const double *cptr = π //ok *cptr = 42; //error,不能经过const指针赋值 double dval = 3.14; cptr = &dval; //ok:可是不能经过cptr来改变dval的值
//能够改变该指针的指向对象 const int v1 = 3; const int v2 = 4; const int *p = &v1; cout<<*p<<endl; //output 3 p = &v2; //改变指向的对象 cout<<*p<<endl; //output 4
任何给const指针从新指向新对象的作法都是错误的。不过,能够经过const指针修改对象的值。编译
int errNumb = 0; int *const curErr = &errNumb; //curErr will always point to errNumb const double pi = 3.14159; const double *const pip = π //pip is a const pointer to a const object
最简单的理解方式是从右往左读,curErr is a constant pointer to an object of type int.class
//能够改变该指针指向对象的值 int v3 = 5; int v4 = 10; int *const p2 = &v3; *p2 = 6; //ok,改变该对象的值 p2 = &v4; //error,由于是const指针,不能从新指向新对象 cout<<*p2<<endl; //output 6
总结:指向const对象的指针 和 const指针 是不一样的。前者认为本身指向的对象是const,因此不能经过该指针修改对象的值;后者认为本身是const指针,不能从新指向新对象。前者能够指向新对象,后者能够更改对象的值。通常来讲,前者用的更普遍,经常使用于函数的传入参数,来保证在函数体中不改变对象的值。