文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C++ 引用参数 深入分析

C++ 引用参数 深入分析

时间:2010-12-14  来源:charley_yang

一、引用参数的三种常见用法:


1.需要改变实参的值,比如swap()。参数是引用时,函数接收的是实参的左值而不是值的拷贝。这意味着函数知道实参在内存中的位置,因而能够改变它的值或取它的地址。
2.向主调函数返回额外的结果。如下例:

/*********************************************************
* Description:  测试引用传递的第二种使用方式
* Author:charley
* DateTime:2010-12-13 23:00
* Compile Environment:win7 32 位 +vs2008

***********************************************************/

#include <iostream>
#include <vector> 
using namespace std;

// 引用参数 'occurs' 可以含有第二个返回值 
vector<int>::const_iterator look_up( const vector<int> &vec, 
                                                                         int value, // 值在 vector 中吗? 
                                                                         int &occurs ) // 多少次? 
{ 
         // res_iter 被初始化为最后一个元素的下一位置  
        vector<int>::const_iterator res_iter = vec.end(); 
        occurs = 0; 
        for ( vector<int>::const_iterator iter = vec.begin(); iter != vec.end(); ++iter ) 
        {
                //判断是否存在value
                if ( *iter == value ) 
                { 
                        //只有第一次找到value时,该项才成立;
                        //找到第二个value时res_iter已经被下一步赋值了,该项不成立
                        //达到在多次出现value的情况下,指向第一次出现的iterator 被返回
                        if ( res_iter == vec.end() ) 
                                res_iter = iter; 
                        ++occurs; 
                } 
        }

        //如果找不到该value值,返问一个指向vector 最后一个元素下一位置的iterator
        return res_iter; 
} 

/**
* 调用look_up方法
*/
int main_test6(){
        vector<int> vInts;
        int iVal;
        cout<<"请输入数字,按Ctrl+Z结束:"<<endl;
        while(cin>>iVal)
                vInts.push_back(iVal);

        if(vInts.size()==0){
                cout<<"没有元素。"<<endl;
                return -1;
        }

        cout<<"您输入的结果如下:"<<endl;
        for(vector<int>::const_iterator iter = vInts.begin();iter!=vInts.end();iter++)
                cout<<*iter<<"\t";
        cout<<endl;
        
        int occurs = 0;
        //查找该容器中是否含有值2。
        vector<int>::const_iterator resIter = look_up(vInts,2,occurs);

        if(!occurs)
        {
                cout<<"容器中不含2。"<<endl;
        }
        else
        {
                cout<<"容器中2出现了:"<<occurs<<"次,*iterator为:"<<*resIter<<endl;
        }
        return 0;
}

3.向函数传递大型的类对象。例如:

class Huge { public: double stuff[1000]; };
extern int calc( const Huge & );
int main() {
Huge table[ 1000 ];
 
// ... 初始化 table
int sum = 0;
for ( int ix=0; ix < 1000; ++ix )
  // 函数 calc() 将指向 Huge 类型的数组元素指定为实参
  sum += calc( table[ix] );
 
// ...
}

二、如果引用参数不希望在被调用的函数内部被修改,那么把参数声明为 const 型的引用是个不错的办法。

如下例:

class X;
extern int foo_bar( X& );
 
int foo( const X& xx ) {
// 错误: const 传递给非 const
return foo_bar( xx );
}
为使该程序通过编译 我们改变 foo_bar()的参数的类型 以下两种声明都是可以接受的 
extern int foo_bar( const X& );
extern int foo_bar( X ); // 按值传递

 

或者可以传递一个 xx 的拷贝做实参 允许 foo_bar()改变它 
int foo( const X &xx ) {
// ...
X x2 = xx; // 拷贝值
 
// 当 foo_bar() 改变它的引用参数时, x2 被改变, xx 保持不变
return foo_bar( x2 ); // ok
}

三、 我们可以声明任意内置数据类型的引用参数

例如,如果程序员想修改指针本身,而不是指针引用的对象,那么他可以声明一个参数,该参数是一个指针的引用,例如:下面是交 换两个指针的函数 

void ptrswap( int *&v1, int *&v2 ) { 
 int *tmp = v2; 
 v2 = v1; 
 v1 = tmp; 
} 

如下声明 
int *&v1;   //实际是为指针取了一个别名,这样就可以通过别名改变指针本身
应该从右向左读,v1 是一个引用,它引用一个指针,指针指向 int 型的对象。

用函数 main() 操纵函数 rswap() 我们可以如下修改代码以便交换两个指针值:

#include <iostream> 
 
void ptrswap( int *&v1, int *&v2 ); 
int main() { 
 int i = 10; 
 int j = 20; 
 
 int *pi = &i; 
 int *pj = &j; 
 
 cout << "Before ptrswap():\tpi: " 
  << *pi << "\tpj: " << *pj << endl; 

//参数为指针的别名(即指针的引用,那么传递的实参就是指针本身,道理和传递普通变量一样的)
 ptrswap( pi, pj ); 
 
 cout << "After ptrswap():\tpi: " 
  << *pi << "\tpj: " << *pj << endl; 
 return 0; 
} 


编译并运行程序 产生下列输出 
Before ptrswap(): pi: 10 pj: 20
After ptrswap(): pi: 20 pj: 10

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载