分享
 
 
 

C++基本功:从一个左右值问题出发,侃侃C++的引用

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

#include <iostream.h>

#include ,stdio.h>

/*--------------------比较的程式1:正常的含有函数的程序----------à

int a[3]={1,2,3};

int function(int index);

int main()

{

int a;

a=function(2);

cout<<a<<endl;

return 0;

}

int function(int index)

{

return a[index];----->返回值

}

*/----------------------------------------------------------------------------

--->

/*------------------比较的程式2-------------------------------------------à

int a[3]={1,2,3};

int main()

{

int b=a[2];-------------->右算子,赋出值

cout<<b<<endl;

a[2]=4; --------------->左算子,被赋值

cout<<a[2]<<endl;

return 0;

}

*///-------->a[i]作为左算子和右算子所表示的意思不同

//----------------------------------------------------------------------------

---à

/*-----------------------比较的程式3----------------------------------------à

int i;

int a[3]={1,2,3};

int &function(int index);

int main()

{

function(2)=9;//--------->可被赋值了

cout<</*a[2]*/i<<endl;

return 0;

}

int &function(int index)

{

// return a[index];

return i;

}/*----------------------------------------------------------------------à

*///----------->利用引用实现通过函数的返回类型的变化.

//--------- -->为什么说:return a[index]返回的应是整形值

//------------>用了引用后明显变了

//------------>不用引用怎样实现上述的效果呢.

//-------- --->即怎样使返回的相当左算子

//------------>怎样理解引用的作用和意义.

你是否感觉:&在几个用法中没有一致的性质可循.

下面我们就来探讨和总结一下:

/*usecase*/ By RedStar81

#include <iostream>

#include <stdio.h>

using namespace std;

void main(void)

{

//测试引用是否可以赋以常量.

/*

int &a =100; //wrong

*/

//考察引用和指针的使用区别

/*

int a = 100;

int *ptr;

ptr = &a;

cout<<*ptr<<endl;

getchar();

*/

//测试对引用取址返回的结果

/*

int a =100;

int &b = a;

cout<<b<<endl;

cout<<&b<<endl;

int &c = b;

cout<<c<<endl;

getchar();

*/

//测试是否可以重新赋值

/*

int a = 100;

int b = 200;

int &c = a;

cout<<a<<endl<<b<<endl<<c<<endl;

c = b;

cout<<c<<endl;

getchar();

*/

//说明引用的一种错误用法..........

/*

int a = 100;

int &b = &a;

cout<<a<<endl<<b<<endl;

getchar();

*/

/*

char* str = "I am programming.";

char*& rpchar = str;

cout<<str<<endl<<rpchar<<endl;

getchar();

*/

//测试引用和指针混合的情况...

typedef char* PChar;

typedef char& RChar;

typedef PChar& RPChar;

PChar str = "I am programming.";

/*

RPChar rpchar; //wrong:not initialized.........

rpchar = str;

*/

RPChar rpchar = str;

cout<<str<<endl<<rpchar<<endl;

getchar();

}

*/

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

/*结论:对于int& a;引用实际是一种隐式指针,是方便编程而引入的,识别由编译器支持

.

在函数的使用中.可把它理解为跟后面的结合. int (&a);

在传递参数的过程中跟取地址值意思差不多.

/* 而在函数内部使用过程中则相当与数值.你可把它看作便利的原因.其实引用&

/* 是一个能自动被编译器逆向引用的常量型指针

总结: ...

/* A.常规使用:

/* 1. int a = 100;

/* int &b = a;

/* 2. int a = 100;

/* int &b = a;

/* int &c = b;

/* 3. int a = 100;

/* int &b; //必须定义时赋值,不同于指针(int a = 100;

/* // int *p; p =&a;)

/* b = a;

/* 4. int &a = 100; //不可将常量赋予引用...

/* const int& a = 100;//可行,作全局看

/* 5. int a = 100;

/* int &b = a;

/* cout<<&b<<endl; //输出的是a(也是b)的地址..而不是指针

/* // 的地址...

/* 6. int a = 100;

/* int &b = a;

/* int *ptr;

/* ptr = &a;

/* cout<<a<<b<<*ptr<<endl; //结果是一样的..注意*ptr.

.

/* 7. int a =100;

/* int b = 200;

/* int &c = a;

/* c = b; //引用可重新赋值...........

/*

/*B.较难的使用规则:

/* 1. 系列错误用法:

/* char* str = "I am programming.";

/* 定义引用数组:int& a[3]; (定义指针数组:int* a[3];

)

/* 定义引用的指针:int&* a; (定义指针的指针:int** pt

r;

/* 定义引用的引用:int&& a;

/* 2. 可定义指针的引用: int*& a = str; //When it must

/* be initialized when definedv.

/*

/*C.引用在函数和对象域的使用

/* 1. 做函数返回类型的应用:(当然传递的参数类型为引用,那么

/* 是地址传递方式...)

/* int arr[3] = {1,2,3};

/* fook(2) = 100; //函数返回的是引用,做左值时,编译

//器将其当作地址使用....

/* //而如返回的是常量,那当然不可

//赋值

/* int& fook(int index){ return (arr[index]+1);}

/*

/* 2.返回局部变量

/* int& fook(param){

/* int m = 100;

/* return m;

/* }

/* //在函数结束生命周期后,返回的地址将不可用.

/*

/* 3.不好的对普通对象的引用

/* class MClass;

/* MClass* mcptr;

/* mcptr = new MClass(param);

/* if(!mcptr) MError("Constructing object failed.");

/* MClass& mcref = *mcptr;

/* 也许上面的引用可以使你感觉更舒服的使用MClass: 如

/* mcref.function();而不必

/* (*mcptr).function();或mcptr->function();

/* 可是相比之下,一个严重的问题来了:内存泄露..

/* 因为引用不像指针那样明显:你很可能忘记:delete &mcref;

/*

/* 4.对对象相关的参数的引用

/* void fook(param1)

/* {

/* param->function(noramlparam);

/* }

/* 上面的程式中,我想传递一个对象的地址,从而使用对象的成员函

/* 数..怎么办?

/*

/* void fook(MClass* mcpptrparam){};

/* 恩,可以.

/* 用一用:

/* MClass mcptr = new MClass(param);

/* fook(mcptr);

/* 还有呢:

/* MClass mcobj;

/* fook(&mcobj);

/*

/* 当然你也可:

/* void fook(MClass& mcrefparam){};

/* 这样引用的对象可在全局数据区、堆栈、栈

/* 5.当然引用真的就是为了方便吗?.......

/* 其实正如它在函数返回值里的应用,可由编译器识别为地址,在作

/* 为对象相关参数的

/* 引用里亦存在同样的好处,指针的引用可替换指针的指针,多变的

/* 工作....

/*

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有