码迷,mamicode.com
首页 > 编程语言 > 详细

C++函数

时间:2015-10-04 22:09:35      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

一.禁止函数返回局部变量的引用

当发生函数调用时,编译器首先把函数的输入/输出参数放到堆栈,指令寄存器IP放到堆栈(作为函数返回出口地址),然后是基址寄存器,接着是函数的局部变量。当函数返回时执行弹出操作,其顺序正好与放到堆栈的顺序相反(首先释放堆栈中的局部存储变量,然后是基址寄存器,IP寄存器地址和函数的输入/输出变量),同时把放到堆栈的IP寄存器地址作为函数的出口地址并退出函数。所以函数的所有局部变量都分配到了堆栈上,当函数退出时堆栈也就释放了,分配局部变量的内存被操作系统重新收回。而函数局部变量所在的内存段具体变成了什么,编程人员无法确定.

所以,函数返回时,保证返回数据超出函数范围后依然有效,如返回局部变量的引入就是不靠谱的事情

函数返回时,返回new生成的对象,同样不是一个可取的方法,因为这样的代码层次混乱,会让代码上层使用人员苦不堪言

二.函数传值。传指针及传引用的效率分析

值传递

char* GetMemory(int nNumber)

{

  char* pStr = new char[nNumber];

  return pStr;

}

int main()

{

  char* pHello = NULL;

  pHello = GetMemory(100);

  strcpy_s(pHello,"Hello,World");

  delete[] pHello;

  pHello = NULL;

}

值传递调用过程分为三步:

1.在堆栈创建形参副本及局部变量

2.函数执行

3.函数退出,释放副本和临时变量。

在副本生成时,如果数据类型为类类型,函数会调用类的构造函数进行类对象构造和数据拷贝,在堆栈释放副本时,如果数据类型为类类型,函数会调用类的析构函数进行类对象数据的释放。

引用传递

char GetMemory(char* &pStr,int nNumber)

{

  pStr = new char[nNumber];

  return pStr;

}

int main()

{

  char* pHello = NULL;

  GetMemory(pHello,100);

  strcpy_s(pHello,"Hello,World");

  delete[] pHello;

  pHello = NULL;

}

引用传值函数三步

1.在堆栈创建引用形参,普通形参副本及局部变量

2.函数执行

3.函数退出,释放(引用)副本和临时变量。

引用传值过程中,即使引用形参为类类型,在副本创建和释放时也不会发生构造和析构函数调用

指针调用3步

1.在堆栈创建指针形参,普通形参副本及局部变量

2.函数执行

3.函数退出,释放副本和临时变量

指针副本即使为类指针,也不会调用类的构造函数,因为创建的不是类对象,而是类指针

指针的解引用就是通常所说的间接寻址,即获取指针变量中内存地址处的数据

差异分析

1.值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟内存空间以存放由主调函数传进来的实参值,从而成为实参的一个副本。被调函数对形式参数的任何操作都作为局部变量进行,不会影响主调函数的实参变量的值。如果想通过传值方式实现两数据的交换,则这种做法不正确。

2.引用传递过程中,被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成指针间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。下

C++函数

标签:

原文地址:http://www.cnblogs.com/fenghuan/p/4855005.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!