引用转载请注明出处,谢谢!
使用引用类型进行返回值的传递经常可以看到,其优点非常明显,如果引用的是对象,可以减少对象传递过程中的对象构造/析构等操作(EffectiveC++ 第三版,第20款),减少CPU资源消耗。但在使用应用的过程中,有些问题也需要注意,下面示例说明。
数据结构:
struct data_header
{
int type;
int length;
...........
};
方法a:
int parse_data(void *rec, char *buffer, int size_buffer, long long &saved_pos )
{
saved_pos = 0;
............
if( xxx )
{
saved_pos = pos;
}
...........
return 0;
}
方法b:
int parse_caller(void *rec, char *buffer, int size_buffer, long long &saved_pos )
{
......................
char *pcur = buffer;
char *pend = buffer + size_buffer;
do
{
int ret = 0;
data_header * head = (data_header*)pcur;
switch( head->type )
{
case 0:
break;
case 1:
ret = parse_data(rec, pcur, pcur-buffer, save_pos);
break;
..................
default:
break;
}
if( ret )
break;
...................
pcur += head->length;
...................
}while( pcur < pend );
return 0;
}
调用过程:
long long save_pos = 0;
int size_buffer = xxxxx;
char *buffer = new char[size_buffer];
...........
for( xxxxxxxx)
{
save_rec *rec = new save_rec;
.................
if( parse_caller(rec, buffer, size_buffer, save_pos) )
{
log("xxxxxxxxxxxx");
delete rec;
delete[] buffer;
return -1;
}
if(save_pos > 0 )
{
.........................
}
.............................
}
整个调用过程看似没有任何问题,但在这个过程中,对于save_pos的赋值操作,结果却是不定的,主要是由于在parse_caller的调用中,可能会多次调用parse_data方法,而parse_data的实现中可以看到,每次在进入方法后都会为save_pos做赋0操作,而只有在某些条件为真的情况下,才会进行有效的赋值。因此,多次的parse_data调用可能会导致前一次的有效值被覆盖。
结论:
对于使用引用类型进行返回值传递的方法,对于引用变量,其初始值的设置最好是放在调用方法外面来完成。