C++中的引用和指针

今天在面试的时候被问到C++和C#中的引用,之前都在复习英语,突然被问起来这些东西,感觉对这些基础知识都有点模糊了。自己用U3D做开发之后也越来越关注游戏场景设计和功能实现,渐渐忽略了基础知识。于是花了些时间梳理了一下。

在C++中,引用最经常被拿来和指针做比较,因为它们的共同点是都可以用来修改内存空间。但指针本身是一个独立的个体,表示所指向内存的地址。而引用是某块内存的别名,就代表那块内存本身。而这点也是两者最本质的区别,网上归纳的许多不同点其实也都由这点推导而出。比如:
指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。int m = 5;int &n = m; int a = 10;n=a;这是改变m和n的值为a,而不意味着n变成了a的引用。m和n之间引用关系不能修改。
sizeof(引用)得到实际变量的大小,sizeof(指针)得到的是指针变量本身的大小。
引用不可以为空,指针可以为空。不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。

在使用上来说,C++的函数参数和返回值的传递有三种方式:值传递、引用传递和指针传递。区别就是后两者可以改变外界传入的参数本身。从这方面讲,可以认为引用起到和指针同样的功效。但指针具有额外的地址运算功能引用并不具备。

从抽象的语义层面来说,引用和指针没有关系,更不是类似的东西。根据More Effective C++里面的规范说明,如果存在不指向任何对象的可能,或者需要在不同时刻指向不同对象,使用指针;如果总是指向一个对象并且指定对象后不会改变指向,使用引用;重载某个操作符时,使用引用。至于底层实现来说,引用也未必一定由指针实现,可能具有与指针相同的实现方式,但具体如何实现取决于不同编译器的设计。

总结来说,关于C++中引用和指针的区别,不能说引用和指针是类似的,或许这样回答比较合适,“引用和指针不同,前者是内存空间的别名,后者指向一段内存空间。二者都可以改变内存空间的值,但指向内存不固定时选用指针,要减少安全风险使用引用。在不同的编译器设计中二者可能具有相同的实现。”

以下代码演示关于指针和引用的区别。

#include
using namespace std;
class Sample{
public:
    Sample():a(1.0){}
    double a;
};
class Test{
public:
    Test():b(a){c=NULL;}
    Sample a;
    Sample& b;
    Sample* c;
};
int main()
{
    int m = 5; // 变量
    int &r = m; // 引用
    int *p = &m; // 指针
    cout << "m: " << m << endl;
    cout << "r: " << r << endl;
    cout << "p: " << p << " *p: " << *p << endl;
    r++; // 引用自增
    p++; // 指针自增
    cout << "m: " << m << endl;
    cout << "r: " << r << endl;
    cout << "p: " << p << endl;
    int a = 6;
    r = a;
    cout << "m: " << m << endl;
    cout << "r: " << r << endl;
    // 指针和引用的内存大小,指针的大小是其本身大小
    // 引用不占内存空间,其大小指被引用对象的大小
    Test T;
    cout << "The size of T: " << sizeof(T) << endl;
    cout << "The size of T.a : " << sizeof(T.a) << endl;
    cout << "The size of T.b : " << sizeof(T.b) << endl;
    cout << "The size of T.c : " << sizeof(T.c) << endl;
    cout << "The type of T: " << typeid(T).name() << endl;
    cout << "The type of T.a: " << typeid(T.a).name() << endl;
    cout << "The size of T.b : " <

你可能感兴趣的:(C++中的引用和指针)