这个话题比较沉重,因为讨论这个话题的小哥哥小姐姐们,基本属于吃多了撑的。但是最还有有人喜欢讨论,所有我也吃多了撑的来讨论一下。
先看一段代码:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
int a = 5;
int b = 50;
int *p;
p = &a;
int &q = a;
// 打印:指针的地址,指针指向的地址,指向指向地址的值
qDebug() << &p << " : " << p << " : " << *p;
// 打印:引用的地址,引用的值
qDebug() << &q << " : " << q;
p = &b;
q = b; // 这次操作是的效果是:把b的值赋给a
qDebug() << &p << " : " << p << " : " << *p;
qDebug() << &q << " : " << q;
return app.exec();
}
运行输出:
0x73fc80 : 0x73fc8c : 5
0x73fc8c : 5
0x73fc80 : 0x73fc88 : 50
0x73fc8c : 50
通过上面我们发现这么几件事:
| 指针 | 引用 |
|---|---|
| 可以先定义,再赋值 | 定义和赋值必须一起 |
| 定义必须是用”左值“ | 定义必须是用”左值“ |
| 定义后可以修改 | 定义后不能在修改 |
| 是一个对象,有自己空间 | 是一个别名,不会被分配空间 |
(Ps:“左值”和“右值”的概念后面再说。)
到这里可以解释一般的问题了,但是事情的本质并没有被揭露。
指针和引用的区别是在编译时确定的:
程序在编译时分别将指针和引用添加到符号表上:符号表上记录的是变量名及变量所对应地址,符号表生成后就不会改变。
指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。
因此指针可以改变指向的对象,而引用对象不能改。这是使用指针不安全而使用引用安全的主要原因。从某种意义上来说引用可以被认为是不能改变的指针,因为引用的底层是用指针常量实现的。