【02】C到C++(引用、内联函数、类型转换)

版权声明:zhuhurry 未经博主允许不得转载    https://blog.csdn.net/zhuhurry

一、引用
引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*。引用(reference)是c++对C语言的重要扩充。引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。其格式为:
类型 &引用变量名 = 已定义过的变量名 int b=10; int &a = b;
引用的特点:
①一个变量可取多个别名。
②引用 必须初始化 。const引用和当引用作为函数参数时可不用初始化
③引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量

1. 基础引用


(1)&在此不是求地址运算符,而是起标识作用、int指引用的目标变量a是int类型
(2)引用不是变量、仅仅只是变量的别名、没有自己独立的空间、要与它所引用的变量共享空间。
(3)对引用取地址就是对变量求地址即:&a == &b == &c,对引用做改变就是对变量做改变。
(4)引用在定义的时候要进行初始化、引用一经初始化,不能重新指向其它变量

2. const引用

(1)const引用引用变量时,变量改变、引用值也会改变。不能直接修改引用值
(2)非常引用不能引用常量,只有常引用才可以引用常量
(3)不同类型的引用引用变量时,会产生一个临时变量,该变量是一个常量,此时该引用引用的是这个具有常性的临时变量。

3. 引用作为参数
引用一个重要的作用是作为函数的参数 ,以往的C语言中进行值传参时,需要创建一个形参并分配空间,这样大大影响了程序的效率。C语言中为了解决这一问题,采用的方案是地址传参,这样可以避免拷贝整块数据,进而提高了程序的效率。
而在C++中提供了一种和指针传参有同样效率的方案,就是引用作为参数。

(1)传递引用给函数与传递地址给函数是一样的,这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;
(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给指针形参分配存储单元,且程序阅读性差

4. 引用作为函数返回值
要以引用返回函数值,则函数定义时要按以下格式:
int &function(int a)
{
//函数体
}
以引用返回函数值,定义函数时需要在函数名前加&
用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。

(1)不能返回局部变量的引用,因为在函数调用结束后,局部变量会被销毁
(2)返回引用的函数值,可作为表达式的左值。

5. 数组引用和指针引用

(1)数组引用格式: int(&b)[10] = a;
(2)指针引用格式: int* &c = p;


二、内联函数
当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系统时间和空间的开销。有些情况下,函数本身功能简单,代码很短,但使用频率却很高,程序频繁调用该函数所花费的时间却很多,从而使得程序执行效率降低。为了提高效率,一个解决办法就是不使用函数, 直接将函数的代码嵌入到程序 中,可以使用带参数的 宏定义实现 ,但是这种方法也有 缺点 ,程序可读性往往没有使用函数的好,如果缺少了一些括号还可能出现歧义。
为了协调好效率和可读性之间的矛盾,C++提供了另一种方法,即定义 内联函数 ,方法是在定义函数时用修饰词 inline 。inline关键字告诉编译器,这个函数的调用要尽可能快,可以当普通的函数调用实现,也可以用宏展开的办法实现。在C99也引入了inline 关键字。
宏实现代码嵌入:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
这个宏在运行时,容易出现问题,如:MAX(++a,++b),展开后变成k = ((++a)>(++b)?(++a):(++b)),a和b 增加的次数就难说了。
内联函数实现代码嵌入:
inline int max(int a, int b)
{
return a > b ? a : b;
}

三、默认参数
C++中可以在函数声明时为参数提供一个默认值
当函数调用时没有指定这个参数的值,编译器会自动用默认值代替
函数默认参数的规则:
只有参数列表后面部分的参数才可以提供默认参数值
一旦在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默认参数值

四、函数占位参数
占位参数只有参数类型声明,而没有参数名声明,一般情况下,在函数体内部无法使用占位参数。



五、类型转换
C风格的类型转化如下:char a=10;int b=(int)a;
为了更好的进行类型转换、C++引入了4个类型转换操作符,static_cast、const_cast、reinterpret_cast和dynamic_cast。
为了有了C风格的类型转换还要引入C++的类型转换?
因为C语言,没有区分const指针和非const指针、基类指针和派生类指针等这些问题,还有一个缺点是程序可读性不强。

1. static_cast
可以实现C++中内置基本数据类型之间的相互转换,enum、struct、 int、char、float等。它不能进行无关类型(如非基类和子类)指针之间的转换。
int c=static_cast<int>(7.987);
如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数:

(1)static_cast可直接转化基本数据类型(int flaot等)。
(2)转换类的类型时不能直接转换对象本身, 只能转换对象的指针或引用
(3)static_cast在 涉及到类的转化的时候,会检查类之间是否存在联系 ,如果不存在联系则两者之间不能进行转换。而C语言风格在转化时,没有检查类之间是否存在关系都可以转化,这样就容易出现不可预知的错误。
(3)假如将float变量的地址,强转成int *指针,如果修改该int *指向的内容,则该float变量的值就乱了,固 不能将一个变量的地址强转成另一种类型的指针 。同理:不 能将一个变量强转成另一个类型的引用 。而C风格强转没有进行这种错误检查。

2. const_cast
用法:const_cast<type_id> (expression)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。

(1) 功能是去除常量的const性
(2)常量指针被转化成非常量指针,并且仍然指向原来的对象;
(3)常量引用被转换成非常量引用,并且仍然指向原来的对象;
(4)常量对象被转换成非常量对象,出错,不能这样操作;

3. reinterpret_cast
此标识符的意思即为数据的二进制形式重新解释,不改变其值,没有任何限制可转换成任何类型。可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值),一般用于 强制类型转换 。不管是什么类型都可以转换
                        
(1)使用reinterpret_cast很危险,比如实例中会混淆b指向的值。加入修改b指向的值,则会导致i值不可估计,固 尽量不要使用reinterpret_cast

4. dynamic_cast
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

















  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值