简单谈谈C++ 中指针与引用
指针和引用形式上很好区别,但是他们似乎有相同的功能,都能够直接引用对象,对其进行直接的操作。但是什么时候使用指针?什么时候使用引用呢?这两者很容易混淆,在此我详细介绍一下指针和引用,力争将最真实的一面展现给大家。如果我喷得不够好,希望嘴下留情、手下留命,还请指点一二;如果感觉还不错,请大家鼓掌。 指向不同类型的指针的区别在于指针类型可以知道编译器解释某个特定地址(指针指向的地址)中的内存内容及大小,而void*指针则只表示一个内存地址,编译器不能通过该指针所指向对象的类型和大小,因此想要通过void*指针操作对象必须进行类型转化。 ★ 相同点: 1. 都是地址的概念; ★ 区别: 1. 指针是一个实体,而引用仅是个别名; ★ 联系 1. 引用在语言内部用指针实现(如何实现?)。 引用的一些规则如下: 以下示例程序中,k 被初始化为i 的引用。语句k = j 并不能将k 修改成为j 的引用,只是把k 的值改变成为6.由于k 是i 的引用,所以i 的值也变成了6. int i = 5; int j = 6; int &k = i; k = j; // k 和i 的值都变成了6; 上面的程序看起来象在玩文字游戏,没有体现出引用的价值。引用的主要功能是传递函数的参数和返回值。 指针能够毫无约束地操作内存中的如何东西,尽管指针功能强大,但是非常危险。 指针与引用,在More Effective C++ 的条款一有详细讲述,我给你转过来 条款一:指针与引用的区别 指针与引用看上去完全不同(指针用操作符‘*'和‘->',引用使用操作符‘。'),但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何决定在什么时候使用指针,在什么时候使用引用呢? 这是非常有害的,毫无疑问。结果将是不确定的(编译器能产生一些输出,导致任何事情都有可能发生),应该躲开写出这样代码的人除非他们同意改正错误。如果你担心这样的代码会出现在你的软件里,那么你最好完全避免使用引用,要不然就去让更优秀的程序员去做。我们以后将忽略一个引用指向空值的可能性。 因为引用肯定会指向一个对象,在C++里,引用应被初始化。 string& rs = s; // 正确,rs指向s 指针没有这样的限制。 string *ps; // 未初始化的指针 // 合法但危险
void printDouble(const double& rd) { cout << rd; // 不需要测试rd,它 } // 肯定指向一个double值 相反,指针则应该总是被测试,防止其为空: void printDouble(const double *pd) { if (pd) { // 检查是否为NULL cout << *pd; } } 指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。 string s1("Nancy"); string s2("Clancy"); string& rs = s1; // rs 引用 s1 string *ps = &s1; // ps 指向 s1 rs = s2; // rs 仍旧引用s1,// 但是 s1的值现在是 // "Clancy" ps = &s2; // ps 现在指向 s2; // s1 没有改变 总的来说,在以下情况下你应该使用指针, 但是这样会使得v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。(这有一个有趣的例外,参见条款30) void func(int* p,int&r); int a = 1; int b = 1; func(&a,b); 指针本身的值(地址值)是以pass by value进行的,你能改变地址值,但这并不会改变指针所指向的变量的值, p = someotherpointer; //a is still 1 但能用指针来改变指针所指向的变量的值, *p = 123131; // a now is 123131 但引用本身是以pass by reference进行的,改变其值即改变引用所对应的变量的值 r = 1231; // b now is 1231 尽可能使用引用,不得已时使用指针。 当你不需要“重新指向”时,引用一般优先于指针被选用。这通常意味着引用用于类的公有接口时更有用。引用出现的典型场合是对象的表面,而指针用于对象内部。 上述的例外情况是函数的参数或返回值需要一个“临界”的引用时。这时通常最好返回/获取一个指针,并使用 NULL 指针来完成这个特殊的使命。(引用应该总是对象的别名,而不是被解除引用的 NULL 指针)。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |