解引用
引用是什么?
引用在很多情况下和指针相似,引用是一个名称,可以用作某个对象的别名。与指针不同,不能是声明引用而不初始化。引用总是真正的别名,除此之外和原始值难以区分。例如,如果取得引用的地址,结果会是一个指向原始地址的指针。必须解除对指针的引用,才能访问它指向的变量,引用不需要解引用,引用在某些方面像解除引用的指针。引用一直与其引用的变量完全对等,因此,引用非常类似于const指针变量。
国外资料出现的一词“reference",应译为”参考,参照“,在我们中文技术资料上翻译为了”引用“,照上面说的那种场景,倒也可以理解的通。而”dereference“翻译为”解除参照“,资料上翻译为”解引用“,如果回到上面那种场景,那”解引用“或者”解除参照“就是:我们拿了(引用)别个作者的话,却没有注解(解除参照)说这是别人的话,实际上我认为”去引用化“也许更能表达这个过程或者这个意思。那么对应到C语言中,指针变量是存储”其它变量“的地址的,当我们用”*“去操作指针时,我们的意思就是把那个”其它变量“的内容拿过来放在这里,却不说明这是别人(在这里就是指针存储的变量)的东西,当然这只是类比。过程差不多相似,只要能帮助理解,就阿弥陀佛了。于是”解引用“这样来理解,貌似好多了。不知道大家懂我说的了没?
上述这段话摘抄自解引用_百度百科 (baidu.com),如果没有展开,就算是指针指向的地址,像上面一段拿出来就算解引用了,即所谓的“去引用化”。
指针与字符串
char * 不可改变。
输出一个指针指向的字符串是很容易的,只需要指出该指针名即可,就像这样:
#include <iostream>
using namespace std;
int main()
{
char *p {"hahahah hahahh hahah"};
cout << *p2 << endl;
cout << p2 << endl;
printf("%s\n",p2);
}
/*
h
hahahah hahahh hahah
hahahah hahahh hahah
*/
指针与const
常量指针:顶层const,指针本身不可变,指向的变量无所谓。
这里怎么理解呢,定义一个指针int *p
,p是定义的指针变量,所以想要p是const,在p的前面加上const就好了,就变成了这样:int * const p
。
int a = 9;
int b = 10;
int * const p = &a;
p = &b;//编译出错
指向常量的指针:指针”认为“指向的值是常量,当然指针可以在中途指向其他的”它认为的“常量,所谓:我指向你,与你有何相干?
定义一个指针int *p
,p是定义的指针变量,所以想要p指向的值是const,在解引用的p的前面加上const就好了,就变成了这样:int const *p
或者const int *p
。这里const不管是修饰*p
还是int
都是同一个意思。
int a = 9;
int b = 10;
const int *p = &a;
int const *q = &b;
*p = b;//被拒绝,我指向的是常量!
指向常量的常量指针:组合以上两种。
指针与数组
可以对指针进行算数运算,修改它包含的地址,只能做加减运算和比较。
指针之差
long numbers[] {10,20,30,40,50,60,70,80,90};
long *p1 {&numbers[6]};
long *p2 {&numbers[1]};
auto diff {p1 - p2};
auto isBig {p1 > p2};
//diff == 5
//isBig == 1
不要使用运算符new和delete,没有特殊需求总是要使用容器和智能指针。
原始指针与智能指针。
三种智能指针:
- unique_ptr<T> 唯一的指针,不能有超过一个unique_ptr<T>对象保存相同的地址。
- shared_ptr<T> 通过引用计数可以有任意多个shared_ptr<T>对象保存相同的地址。
- weak_ptr<T> 被链接到shared_ptr<T>上,包含相同的地址,创建不会递增所链接的shared_ptr<T>对象的引用计数,所以不能防止它指向的对象被释放。一直用途是避免创建shared_ptr<T>对象的引用循环。弱指针不经常使用。
使用智能指针
总是应该使用make_来创建智能指针对象。
auto p1 { std::make_unique<double>(999.0) };
auto p2 { std::make_unique<double> {new double {999.0} };
智能指针的函数:
- get()函数,返回该指针包含的地址。
- reset()函数,可以把任意类型的智能指针包含的指针重置为指向nulltpr。
- release函数,用于将智能指针转换为原始指针,调用该函数一定要保存得到的原始指针。
尽可能不要调用release(),因为有可能引入内存泄漏。使用release()后,智能指针不再负责释放内存,但是因为没有保存原始指针,也无法手动对其delete。
智能指针与面向对象
待续。