C++之指针与引用
指针和引用的区别?
在C++的编码中我们发现很多地方都大量地使用引用,能用指针实现的功能用引用几乎也能实现,甚至因为引用不需要拷贝的特性,使用起来比指针性能更高。 那么指针和引用又有什么区别呢?
更多关于指针的内容可以参考《C++之指针扫盲》
1、指针可以为空,引用必须初始化,引用不能为空
string& rs; //错误,引用必须初始化
2、指针可以被重新赋值,但是引用不行。也就是指针可以重新指向另外一个对象,而引用却不行,引用一直指向的都是最初的那个对象。
int main() {
string s1("hello");
string s2("world");
string &rs = s1;
string *ps = &s2;
rs = *ps; // 这不是将引用rs指向ps,而是将s1的值修改为了s2的值
ps = &s1;//将ps重新指向s1
std::cout << "s1:" << s1 << endl;
return 0;
}
3、指针可以有多级,而引用只能是一级,例如我们平时说的指向指针的指针,也就是二级指针,但是就没有所谓的指向引用的引用。
4、有了指针为什么还需要引用?我们都知道指针在使用过程中需要特别地小心,很容易就出现空指针、野指针等令人诟病的问题。但是引用因为它自始至终都是指向一个单一的对象,所以引用比指针更具安全性, 而且使用引用在处理C++的某些问题更加的得心应手,例如运算符的重载等。
5、有了引用为什么还需要指针?在C++中既然有了引用,设置引用的性能比指针更高点,那么为什么还需要指针呢?为了兼容C语言。
6、返回引用还是返回指针?这个要看具体的使用场景,如果作为函数的返回值,C++明确表明是不可以返回布局对象的引用的,因为局部对象在函数返回后就会被析构掉,所以返回它的引用也就没有了意义。但返回非局部对象的引用是允许的,例如STL中vector中按下标取值就可以返回一个引用。如果确实需要返回一个局部对象的话,可以返回一个在堆中的对象指针,暗示返回一个布局对象的指针的话会引发另外一个问题, 那就是这个指针什么时候释放呢?由谁来释放呢?一旦管理不好,内存泄漏是分分钟的事情。因此如果是非局部对象的话可以返回对象的引用,否则可以按值返回,按值返回特别是在C++11之后已经自带了RVO优化, 可以放心使用,更多RVO相关只是可以看我之前的文章《C++之RVO返回值优化》 。
7、指向指针的引用
首先要说明的是指向指针的引用,它是一个引用,而不是指针,指针本质上来说是一个内存地址,但是引用并不是一个对象,引用不会开辟新的内存空间,所以不存在着指向引用的指针这么一说。
例如下面的示例代码:
int i = 100;
int *p;
int *&r = p; // r是一个引用,引用类型是指针
r = &i; //因为r是一个引用,所以给r赋值,就是将p指向i
*r = 0; // 解引用r,也就是将指针p指向的值改为0,也就是将i改为0
从右向左阅读,r的定义离变量名最近的符号(此例中是&r的符号&)对变量的类型有最直接的影响。因此r是一个引用,它引用的对象是一个int类型的指针。
小结
引用和指针并不是一个一山不容二虎的情景,它们的共存是为我们更好的解决问题提供了更加更好的选择!!!
引用本质上也是通过指针的解引用(即*_point)来实现的,可以《参考std源码剖析》一书,所以引用也可以实现多态。
关注我,一起进步,人生不止coding!!!