1. 初始化
引用: 在创建的时候必须初始化,是初始化,初始化,即:引用到一个有效对象上面
指针: 在创建的时候可以初始化也可以在定义后在其它地方再赋值
2. NULL
引用:不存在NULL的引用,必须与合法的存储单元关联
const &int a = 0; //并非是初始化null,而是创建临时对象int然后初始化为0,再引用这个临时的int对象。
//这个临时对象会一直保留到a销毁才会销毁,因此,不建议使用字面常量来初始化引用
指针: 可以为NULL
3. 更改指向
引用: 从一而终,矢志不渝,一旦被初始化指定为一个对象,就不能更改为另外一个对象
int a = 100; int b = 20;
int &c = a;
c=b; //注意: 这并非是让c改变指向,由a到b,而是改变a的值,将b赋值给a,c的引用一直都是a。
//还有一种叫法:引用就是变量的别名,c就是a的另外一个名字,所以此处就是把b赋值给a,将a的值改掉了。
指针: 随时改变
4. 引用创建和销毁不会调用类的拷贝构造和析构函数
class Fctor { public: Fctor() { std::cout << "Fctor" << std::endl; } virtual ~Fctor() { std::cout << "~Fctor" << std::endl; } Fctor(Fctor &fc) { std::cout << "Fctor &fc" << std::endl; } void operator() () { std::cout << __FUNCTION__ << "###" << "exit" << std::endl; } }; int main() { { Fctor fc1; Fctor &fc2 = fc1; } }
输出:
Fctor
~Fctor
总结:
使用上,引用的用法和对象一样,实现上,引用一般通过指针来实现的,只不过编译器帮我们完成了转换
引用即具有指针的效率,又具有变量的方便性和直观性
最直接的用途:修饰函数的形参和返回值。
c时代,一般函数的参数和返回值的传递方式有二种:值传递和指针传递----具体效果不多说,直白就是:指针传递函数内改变可以影响函数外,值仅仅传递的是一个拷贝,不影响原来
c++中,新增引用后,多了一种引用传递, 使用效果上与传递指针一样,书写上面与值传递一样。
建议使用引用传递, 值传递会有拷贝,对象过大的话,多一个拷贝会造成浪费,指针传递的效果引用也能达到,避免了指针使用的一些risk。
后话:
实际上引用能做的,指针都能做,为什么还要引用?
个人理解: 主要是指针太过自由,太过于强大,因此c++新增了引用,体现最小特权原则,满足能完成功能的指针的最小权限,限制了指针的一些其他危险的操作,随意访问内存。
举个可能不是很恰当的列子,如: 现在有一份证明需要盖公章, 引用类似我来给你盖好章就行了,只盖这一份,不会盖别的。
指针类似就是我把章给你,你自己来盖,这个自由度就比较高了,你可以拿着章去盖别的。。。。。。