引用的作用[VC/C++编程]
本文“引用的作用[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
众所周知,引用作为函数参数可以避免参数对象的额外拷贝,关于非内置范例,普通而言可以得到更高的效率,同时比指针更安全,语义也更清楚.但是除此之外引用有什么分外的作用呢?在同一个作用域的引用,就像这样:
void f()
{
int i = 0;
int &ri = i; //这里.
//...
}
事实上,在f的内部,需求操作i的地方,完好可以直接利用i,而不必要利用ri间接操作,利用i在语义上更明确.而混合利用i和ri反倒简单惹起逻辑的混乱.
仿佛这是一个鸡肋,但是其实不是.
这里引用乾坤一笑文章中的例子:
例1、用C宏,书写代码更简便
这段代码写网络程序的朋友都很眼熟,是Net/3中mbuf的实现.
struct mbuf
{
struct m_hdr mhdr;
union {
struct
{
struct pkthdr MH_pkthdr; /* M_PKTHDR set */
union
{
struct m_ext MH_ext; /* M_EXT set */
char MH_databuf[MHLEN];
} MH_dat;
} MH;
char M_databuf[MLEN]; /* !M_PKTHER, !M_EXT*/
} M_dat;
};
上面的代码,假定我想拜候最里层的MH_databuf,那么我必须写M_dat.MH.MH_dat.MH_databuf; 这是不是很长,很难写呀?这样的代码阅读起来也不明了.其实,关于MH_pkthdr、MH_ext、MH_databuf来说,固然不是在一个构造层次上,但是假如我们站在mbuf之外来看,它们都是mbuf的属性,完好可以压扁到一个平面上去看.所以,源码中有这么一组宏:
#define m_next m_hdr.mh_next
#define m_len m_hdr.mh_len
#define m_data m_hdr.mh_data
... ...
#define m_pkthdr M_dat.MH.MH_pkthdr
#define m_pktdat M_dat.MH.MH_dat.MH_databuf
... ...
这样写起代码来,是不是很精练呢!
这里用宏很巧妙的办理了拜候深层数据的问题,但是宏的固有缺陷也被引入了代码中,同时,假如其他地方无意中引用了这个宏定义的头文件,并且刚好利用了名为m_pktdat的数据成员,那这个宏带来的后果可就不是我们想要的了.
事实上用引用也可以到达近似的效果,不过必须是在利用的时刻.由于引用不是尺度C的构成部份,所以这只是一个C++本领.
//假定代码是这样的:
mbuf m; //这里的mbuf就是前面的struct mbuf.
//假如要利用MH_ext成员,可以这样:
m_ext &MH_ext = m.M_dat.MH.MH_dat.MH_ext;
//然后你的代码中便可以直接利用MH_ext作为m.M_dat.MH.MH_dat.MH_ext的替换品了.
大概看起来不是很自然,不过这无疑是一种很直接的办法.你还可以通过一个const引用来在逻辑上避免无意的写操作.
实际的“面向对象”的C++代码中,不举荐直接数据成员的拜候,取而代之的是利用Get()和Set()办法存取数据,有些人只利用Get,通过返回一个成员的引用来到达读写数据成员的双重目的,这时刻,你可以在外部定义一个引用承受函数的返回,从而避免每次都要写(XXX.Get()).Get()这种拖沓的语句来拜候一个深层的成员.
引用的另一个作用,就是“别名”.别名是引用的另一种翻译,很明确的表达了引用的另一个作用.仅仅是为了代码的可读性:
//下面的代码
int i = 0,j = 0;
//...
for( i = 0; i < 10; i++)
for( j = 0; j < 10; j++ )
a[i][j] = 0;
//你能懂得这段代码的含义嘛?有点艰难,i和j的含义是不明确的,无法一眼看破.
//假定改成这样:
const int width = 10;
const int height = 10;
//...
int i = 0,j = 0;
//...
int &line = i;
int &row = j;
for(line = 0;line < height;line++)
for(row = 0;row < width;row++)
a[line][row] = 0;
//是不是好了一点?
这并非一个典型的例子,因为i和j的定义是肆意的,某些情形你必须利用别人给定的名称很忧郁的变量,而他们又必须用来表达截然差别的含义,这时刻一个引用常常可以让你清爽很多.
再看下面这个例子:
class CA
{
int m_i;
public:
int &i;
int const &c_i;
CA():i(m_i),c_i(m_i){};
};
这是一个简单的类,与所谓的“面向对象”的办法差别,这里利用引用实现内部数据的公用接口.这个伎俩用来对应 乾坤一笑 的另一段话:
这就是偶说的PME模子的问题了,delphi、java、c#之类的语言都供应一种叫做属性的语法,大约是这个模样的:
class A
{
property int x
{
get {return x;}
set {x = value;}
}
};
A a;
这样, 便可以这么拜候了 a.x = 8; int b = a.x;
这比用 a.setx(8); b=a.getx();直观多了.
你可以用 CA a; a.i拜候CA的私有数据成员,到达像属性办法那样的效果.但是这个办法在VC6下的表现却不尽如人意,因为它存储了一个指针用来代替语法上的引用,这招致类体积不必要的扩大,是我们所不但愿看到的.大概在实现上确切存在难度,不过还是但愿有更好的编译器能实现真正意义的引用接口.
这个例子其实是上面深层数据成员拜候的一个引伸.
引用,作为C++的一个特别伎俩,大概还有很多不为人知的作用等候我们去发掘呢~
注:文中的代码并未经过严峻测试,有爱好的读者可以自己测试代码的有效性.
以上是“引用的作用[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:<b>常用端口大全</b>
- ·下一篇文章:<b>《UTF-8与GB2312之间的交换》的改良</b>
- ·中查找“引用的作用”更多相关内容
- ·中查找“引用的作用”更多相关内容