C++中以复合数据类型为返回值的函数

前言

不同于C语言其实是汇编语言的高级版本,c++有着自己的语言特性,就如同Java、Python一样,这些特性的实现细节由编译器实现,并对使用者透明。而C++中最常用到的思想就是对象思想,把任何事物抽象成一个对象,对象由两个维度组成:数据操作(数据就是C语言中的结构体),而操作中又有一部分是必须的,这也是编译器为我们提供默认函数的原因。C++和C另外一个重要的不同在于C++中规定编译器对于一些函数的隐式调用,如在初始化对象时对构造函数的隐式调用,对象赋值时对赋值运算符的隐式调用,这样规定的好处是代码编写量更小,但是也对使用者对C++标准的了解程度提出了更高的要求。
在C++中,每个类有以下几种默认的函数:

  1. 默认构造函数;
  2. 默认拷贝构造函数;
  3. 默认析构函数;
  4. 默认重载赋值运算符函数;
  5. 默认重载取址运算符函数;
  6. 默认重载取址运算符const函数;
  7. 默认移动构造函数(C++11);
  8. 默认重载移动赋值操作符函数(C++11)。

以对象为返回值的函数

我们先来看两个函数

int f1(){
int Tmp;
....
return Tmp;
}

A f2(){//f2是一个类
A Tmp;
....
}
return Tmp;
int main(){
int a=f1();
A b=f2();
}

让我们思考一下这两个函数有什么区别?区别在于返回值的数据类型不同,f1的返回值是一个基本类型,而f2的返回值是一个复合类型。我们知道,在c++中,一个类似于这样的语句T xx=function(),编译器的处理步骤一般为:

  1. 调用function;
  2. 将function的结果通过mov等汇编指令赋值为xx变量所在的内存单元;

我们更仔细的来想一下第二步中的结果的存储位置:在执行到第二步时,我们已经从函数返回了,对于函数中的局部变量已经不能进行访问,那么我们的结果究竟保存在哪里呢?对于诸如返回类型为char等基本数据类型的函数来说,可以通过寄存器(通常是eax寄存器)。进行传值而对于结构体、对象等复杂数据结构来说,无法通过寄存器保存。一种妥协的方法是通过某种方式(在 MSVC下是调用者的栈空间)开辟一段内存,并将结果从局部变量拷贝到该段内存中,注意:这段内存是无名字的,所以也叫将亡值

总结一下,假设函数流程如下:

A f2(){//f2是一个类
A Tmp;
....
return Tmp;
}
return Tmp;
int main(){
A b;
b=f2();
}

f2函数的在MSVC中的流程如下:
1.调用者(main函数)将将亡值的空间地址传入f2;(这一步对开发人员不可见)
2. f2做该做的事情;
3. f2调用A的拷贝构造函数将临时对象拷贝到将亡值空间中;
4. main函数调用赋值运算符函数完成该语句;
5. main函数调用将亡值的析构函数负责收尾;

另外对于语句A b=f2();需要做一点特殊的说明,该语句实际上被转化为A b(f2()),同时该语句的执行流程和上述一致,但是第四步和第五步不需要做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值