pointers 指针
raw pointers
内存是计算机最重要的,内存是线性的
指针
在内存中存放地址的整数,不保存数据
指针需要类型的原因:需要知道内存,如果选用void类型,则会出错
c++11:可以设置空指针为 nullptr
#include <iostream>
#define Log(x) std::cout<< x << std::endl;
int main() {
void* ptr = nullptr; //类型不能决定指针,指针只是一个地址;0意味着无效
int var = 8;
int* ptr2 = &var; //拿到变量地址,16进制
*ptr2 = 10; //解引用该指针,访问该data,也可以进行读取或者写入
Log(var);
std::cin.get();
} //最后输出为10
memset
#include <iostream>
#define Log(x) std::cout<< x << std::endl;
int main() {
char* buffer = new char[8]; //为我们分配了8字节内存,并返回一个指向这块内存的开始地址的指针
memset(buffer, 0, 8);//用指定数据填充一块内存,接受一个指针指向这块内存的开始,8表示填充多少的字节
std::cin.get();
}
指针的指针
int main() {
char* buffer = new char[8]; //为我们分配了8字节内存,并返回一个指向这块内存的开始地址的指针
memset(buffer, 0, 8);//用指定数据填充一块内存,接受一个指针指向这块内存的开始,8表示填充多少的字节
char** ptr = &buffer;
delete[] buffer;
std::cin.get();
}
我们输入ptr的地址,将 b0 c4 57 4b b2 01 00 00 逆序,变成000001b24b57c4b0,则会跳转到存储buffer的地址
smart pointers
reference 引用
并不是变量,只是一个别名
格式
int& ref = a;
string *ps; //未初始化的指针,有效,但风险高
int main() {
int a = 5;
int& ref = a; //ref不是一个变量,只是一个别称;这个ref变量并不真正存在,他只存在我们的源码里
ref = 2;
std::cout << a << std::endl;
std::cin.get();
}//输出为2
实例
下面的输出为5,a并没有增加
void increment(int value) {
value++;
}
int main() {
int a = 5;
increment(a);
std::cout << a << std::endl;
std::cin.get();
}
正确的做法
传递这个a地址进去
void increment(int* value) {
(*value)++;
}
int main() {
int a = 5;
increment(&a);
std::cout << a << std::endl;
std::cin.get();
}
引用传递
void increment(int& value) {
value++;
}
int main() {
int a = 5;
increment(a);
std::cout << a << std::endl;
std::cin.get();
}
错误示范
必须立即将一个实际变量赋给他
//实例1:未立即赋值
int& ref;
ref=b;
//实例2:编译器可能产生任何可能的输出,行为有害!
char *pc=nullptr;
char& rc=*pc;
一旦申明,则不能更改对象
int main() {
int a = 5;
int b = 8;
int& ref = a;
ref = b; //ref仍然指向a,但是值变成b的值
std::cout << a << std::endl;
std::cin.get();
} //最终输出 a=8
差异
-
没有所谓的null reference,这也意味着使用reference可能会比使用指针更富效率,因为不需要测试有效性,使用pointer则需要检测其是否为null
void printdouble(const double *pd){ if(pd){ //检查是否为null cout << *pd; } }
-
指针可以被重新赋值,reference却总是指向最初获得的对象
总结
你需要考虑“不指向任何对象”的可能性时,或是考虑“在不同时间指向不同对象”的能力时,你就应该采用 pointer。前一种情况你可以将 pointer设为 null,后一种情况你可以改变 pointer 所指对象。
而当你确定“总是会代表某个对象”,而且“一旦代表了该对象就不能够再改变”,那么你应该选用 reference。还有其他情况也需要使用 reference,例如当你实现某些操作符的时候。最常见的例子就是 operator[]。这个操作符很特别地必须返回某种“能够被当做assignment 赋值对象”的东西
当需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由 pointers 达成,你就应该选择 references。任何其他时候,请采用 pointers
要使用 reference,例如当你实现某些操作符的时候。最常见的例子就是 operator[]。这个操作符很特别地必须返回某种“能够被当做assignment 赋值对象”的东西
当需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由 pointers 达成,你就应该选择 references。任何其他时候,请采用 pointers