免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: lipingtababa

[C++] 你们的代码会用引用吗? [复制链接]

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
发表于 2008-11-18 21:21 |显示全部楼层
估计说引用比指针好n多的,指针可以被引用取代的,大多都是写惯了高级语言的人。
从实现上讲,引用和指针原本就是一回事。
有人说一些引用无法被指针取代,比如拷贝构造函数云云,其实只要编译器支持,又怎么会取代不了?
有人说引用比指针安全,比如void func(int& p),p不会是空指针,但是如果别人要这么调用func(*(int*)NULL),两者又回到同一起跑线,其实安不安全主要取决于作者。
那么又为什么要搞个引用出来?
个人估计,一是因为写Variable.elem比写lpVariable->elem要快,二是将一个函数分割为多个函数时一些相关变量不需要修改为指针的形式。
说白了,就是为懒人服务的……

256色位图信息头,不想使用指针和new的写法:

  1. char buffer[sizeof(BITMAPINFOHEADER] + sizeof(RGBQUAD) * 256];
  2. BITMAPINFO& bih = *(BITMAPINFO*)buffer;
  3. //bih.
复制代码

以上完全可以用指针替代,只不过这样看起来舒服一点,写起来稍微方便一些而已。

论坛徽章:
0
发表于 2008-11-18 21:22 |显示全部楼层
楼主,我来给你你想要的答案,从二者的区别入手。
(1)非空区别。在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让他指向一个对象,但是该变量在某些时候也可能不指向任何对象,这是你应该把变量声明为指针,因为这样你可以赋予空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。不存在指向空值得引用这个事实意味着使用引用的代码效率比使用指针要高。
(2)合法性区别。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)可修改区别。指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则是总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象其内容可以改变。
(4)应用区别。总的来说,在以下情况下你应该使用指针:一是你考虑到存在不指向任何对象对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。

技术肯定是要慢慢积累的,但有时候指引也是很必要的,我说的对吗,前面的高手们

论坛徽章:
0
发表于 2008-11-18 21:25 |显示全部楼层
31楼说引用是为懒人服务,我是比较同意的,不过我的原则是能懒就懒

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
发表于 2008-11-18 21:42 |显示全部楼层
32L的(1)和(2):

  1. void func(int& p)
  2. {
  3.        //if (&p != NULL)
  4.             printf("%d",  p);
  5. }
  6. int main(int, char**)
  7. {
  8.      func(*(int*)NULL);
  9. }
复制代码

此时p是一个指向NULL的引用,加上判断程序正常,否则挂掉。
当然没人会傻到这么写,这就跟在void func(int* p /*Can not be NULL*/)这样的注释下,别人还要传NULL做参数,却抱怨指针不好用一样可笑。

(3):

  1. class U
  2. {
  3. public:
  4.         U(int u) : p(u) {};
  5. public:
  6.         union
  7.         {
  8.                 int& p;
  9.                 int* q;
  10.         };
  11. };

  12. int main(int, char**)
  13. {
  14.         int a = 0, b = 1;
  15.         U u(a);
  16.         printf("%d, ", u.p);
  17.         u.q = &b;
  18.         printf("%d\r\n", u.p);
  19.         return 0;
  20. }
复制代码

一次是0,另一次是1,U::p这个引用被指到了不同的地址。

论坛徽章:
0
发表于 2008-11-18 22:20 |显示全部楼层
我喜欢引用,因为我讨厌指针的解引用。我觉得不好看。而且层数多了会让我晕

论坛徽章:
0
发表于 2008-11-18 23:31 |显示全部楼层
>> 那时候怎么也不明白为什么C++要引入引用,我坚持认为引用肯定有独特之处,之所以引入它,肯定是因为指针不够强大.

“引用肯定有独特之处”,这是肯定的;“之所以引入它,肯定是因为指针不够强大”,就不确切了。指针再强大,也有它照顾不到的地方;指针和引用也不是非此即彼的关系,它们有交叉,又有区别(自己独特的地方)。作为一个 C++ 程序员,要根据情况使用它们:有时用指针比较合适,有时非引用不可,有时又两者皆可用。

>> 后来写多了代码,我觉得这个玩意的引入完全是多余的,他所有的功能都可以被指针取代(实际上它也是用指针实现的).

参加下贴:
http://bbs.chinaunix.net/viewthr ... p;page=1#pid8249864

>> 比如最常用的 void fun(const Type& para)就可以用 void fun(const Type* p_para)取代.

不能完全取代。例如,对于前者可以这样调用 fun( Type() ),但是后者的调用要求实参必须是一个左值。

>> 我还见过类似 void fun(Type* & p)的代码,真是难看啊, void fun(Type ** pp)直接明了多了.

较之后者,我觉得前者的语义明确多了,不用象指针那样绕来绕去的。

>> 从实现上讲,引用和指针原本就是一回事。

不要人云亦云。引用和指针根本不是一回事,不论是语义上还是实现上。有这样的一个概念作为基础,更有助于你理解引用的本质。

>> 有人说一些引用无法被指针取代,比如拷贝构造函数云云,其实只要编译器支持,又怎么会取代不了?

基于值传递语义的对象拷贝构造函数事实上是实现不了的(或者说即使编译器允许这样的实现,也是不能被实际使用的),只能是基于引用语义的。

>> 有人说引用比指针安全,比如void func(int& p),p不会是空指针,但是如果别人要这么调用func(*(int*)NULL),两者又回到同一起跑线,其实安不安全主要取决于作者。

如果你不用指针的话,又何来 *(int*)NULL 这样的指针解引用的表达式呢?

当然,即使只用引用也可能会出现引用实际不存在的对象的情况,但是与指针比起来,这样的情况少多了。

评分

参与人数 1可用积分 +10 收起 理由
cugb_cat + 10 我很赞同

查看全部评分

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
发表于 2008-11-18 23:47 |显示全部楼层
原帖由 flw 于 2008-11-18 18:10 发表


我觉得还是慢慢积累吧。


积累就积累.
呕吐算是什么

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
发表于 2008-11-18 23:53 |显示全部楼层
让我看就一个糗样,有什么区别???
自己爱怎么用就怎么用

论坛徽章:
1
技术图书徽章
日期:2014-03-06 15:32:30
发表于 2008-11-19 00:16 |显示全部楼层
#include <map>
using namespace std;
typedef map<int, int> _INT_MAP;
void f()
{
  _INT_MAP tmp_map;
  tmp_map[1] = 2;//有了引用就可以这样写
}

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
发表于 2008-11-19 00:26 |显示全部楼层
原帖由 whyglinux 于 2008-11-18 23:31 发表
>> 比如最常用的 void fun(const Type& para)就可以用 void fun(const Type* p_para)取代.

不能完全取代。例如,对于前者可以这样调用 fun( Type() ),但是后者的调用要求实参必须是一个左值。

>> 从实现上讲,引用和指针原本就是一回事。

不要人云亦云。引用和指针根本不是一回事,不论是语义上还是实现上。有这样的一个概念作为基础,更有助于你理解引用的本质。

>> 有人说一些引用无法被指针取代,比如拷贝构造函数云云,其实只要编译器支持,又怎么会取代不了?

基于值传递语义的对象拷贝构造函数事实上是实现不了的(或者说即使编译器允许这样的实现,也是不能被实际使用的),只能是基于引用语义的。

>> 有人说引用比指针安全,比如void func(int& p),p不会是空指针,但是如果别人要这么调用func(*(int*)NULL),两者又回到同一起跑线,其实安不安全主要取决于作者。

如果你不用指针的话,又何来 *(int*)NULL 这样的指针解引用的表达式呢?

当然,即使只用引用也可能会出现引用实际不存在的对象的情况,但是与指针比起来,这样的情况少多了。


1、VC编译器可以写fun(&Type())。
2、经验所致,非云云,union的例子很能说明两者到底是不是同一回事,对于存在编译优化而言,不管你是用引用还是指针, 编译的最终结果都是一样,指针也可能会被优化没掉,就像“别名”一样。
3、拷贝构造,这个你会错意了。只要编译器支持写成指针形式也当作拷贝构造,那么引用就被指针替代了,并不是指值传递。
4、这个你自己也说了可能会有不安全的情况,那我也不用多说了。本来安不安全主要就取决于作者的水平……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP