正确使用C++(2)注意使用C++的引用

首先说我的观点:尽量少使用引用。

 

呃,有人会拿某些名著中的观点压我了。

 

从前几天有个朋友问我的例子说起,看下面的代码:

 

template<typename T, size_t N>

void array_init(T (&a)[N]);

 

他问我的是,这个a前面为什么要有一个引用?很好的问题啊,读者不妨先想想。

 

实际上他是知道要用引用的,因为他试过去掉那个引用,会编译不过,而对于编译信息又不懂,实际上他问的是‘为什么那里不能没有&’?好了,我不打算在这里解释这个问题,如果感兴趣可以email我。

 

引用很难用,所以我们要限制它。降低C++代码的复杂度,提高产品质量才是最重要的。我们要否决掉哪些用法呢:

(1)引用返回。引用为什么要作函数值返回?局部变量是不能引用返回的,那必须返回函数外的值,函数外的值是通过指针或引用传进来的,后面会说不要引用作传出参数,所以没有机会引用返回,你要说 return *this;这种用法是吧,这是很错误的作法,其实上质量更好的代码规范会让你一行只作一次函数调用,你写cout << x << y这种代码,如果出了问题指向这一行我怎么知道是前一个<<还是后一个<<出了问题?像boost::lambda这种甚至于先调哪一个都看不出来,别想了,一行做一件事,老老实实写代码吧。

(2)引用作传出参数。比如std::swap(a,b),标准函数都这样用,我为什么不能?这个是因为,你写的代码还未测试。一个理由是这样的,作为测试人员或其它同行,看到你的代码,其它从调用的地方知道参数是传入还是传出,像这样的写法Foo(a,b,&c,&d)前2个传入后2个传出,很容易理解。好,这个理由不够充分,另外一个理由是,引用传出没办法作空指针判断。你要说引用怎么会有空指针?我可以这样用std::swap:

int a;

std::swap(a, *(int*)NULL);

编译器连个屁都不会放,你运行下试试。当然工程代码中可能不会有这么明显的空指针,但是隐藏中的空指针很多。

 

剩下的用法,const引用作传入参数,对于一些大的结构可以这样用,注意加const,别偷偷传出;引用别名,对于一个很长的结构中的结构,我有时候用,理由是不想让一行代码太长。

 

顺便一提所有C++程序员都关注的C++0x,具体点说就是VC2010,前不久的消息说它发布delay,所以大家兴奋的期待时间延长了。C++0x中有一种右值引用,它能接受临时变量的引用,左值引用的赋值或构造是会引起拷贝的,而右值引用不会,它正如定义的形式一样它是引用的引用,它只会把对象的地址移动过去。

posted @ 2010-01-03 19:19  rick2009  阅读(257)  评论(0)    收藏  举报