shell 函数传递参数_自学C++基础教程(函数重载与函数参数传递中的内存管理)...

38ee0bc767c825a9ffc7ccc0057909fb.png

函数重载

所谓函数重载是指同一个函数名可以对应着多个函数的实现。

确定函数实现时,要求从函数参数的个数和类型上来区分。

  1. 参数个数不同
  2. 参数类型不同。

为什么要重载一个函数名?

希望定义一组函数,它们执行同样的动作,但是应用在不同的参数类型上。

例如:假设定义一个函数,它返回参数中的最大值。

如果没有重载一个函数名的能力,那么我们就必须为每个函数给出一个惟一的名字 例如如下定义一组 max()函数:

int i_max( int, int );

float f_max( float,float );

double d_max( double,double );

这些函数都执行了相同的动作,都返回参数集合中的最大值,从用户的角度来看,只有一种操作,就是判断最大值。至于怎样完成其细节,函数的用户一点也不关心。

这种词汇上的复杂性不是判断一组数中最大值问题本身固有的,而是反映了程序设计环境的一种局限性。在同一个域中出现的名字必须指向一个惟一的对象,函数,class 类型等等。

这种复杂性给程序员带来了一个实际问题,他们必须记住或查找每一个名字,函数重载把程序员从这种词汇复杂性中解放出来。

在 C++中,可以为两个或多个函数提供相同的名字,只要它们的每个参数表惟一或者是参数的个数不同,或者是参数类型不同,下面是重载函数 max()的声明:

int max( int, int);

float max( float,float );

double max( double,double );

在代码区键入如下代码,编译运行查看结果:

254fbb5eed530d5e8f3cdfff685d2a9c.png
#include <iostream>
using namespace std;


int max(int a,int b)

{
	return a>b?a:b;

}

float max(float a,float b)

{
	return a>b?a:b;

}
double max(double a,double b)

{
	return a>b?a:b;

}
void main()

{
	cout<<max(3,5)<<endl;

	cout<<max(3.14f,1.23f)<<endl;

	cout<<max(2.0,1.5)<<endl;
	system("pause");
}

如果两个函数的返回类型和参数表精确匹配,则第二个声明被视为第一个的重复声明,例如:

void print( const string &str );

void print( const string & );

如果两个函数的参数表相同,仅仅是返回值类型不同,那么第二个函数声明被视为第一个函数声明的错误重复声明,会导致程序产生编译性错误,例如:

unsigned int max( int _a, int _b );

int max( int , int );

函数的返回值类型不同,不能构成函数的重载

在代码区键入如下代码,编译运行查看结果:

#include <iostream>
using namespace std;

int   max(int a,int b)
{
	return a>b?a:b;
}
float   max(int a,int b)

{
	return a>b?a:b;

}

double  max(int a,int b)

{

	return a>b?a:b;

}
void main()

{
	system("pause");

}

编译器将会提示如下错误:

bce9710387b55130599604fede6ab0d3.png

如果在两个函数的参数表中,只有可选参数不同,则第二个函数声明被视为第一个函数的重复声明,例如:

#include <iostream>

using namespace std;


int max(int _a , int _b = 3)

{
	return _a>_b?_a:_b;

}

int max(int _a , int _b = 4)

{
	return _a>_b?_a:_b;

}
void main()

{
	max(2);
	system("pause");

}

编译器将会提示如下错误:

70c6c377a27cfd770177041646461671.png

仅仅靠修饰符const 标注的参数,如果参数的类型一样,则也不能构成函数重载,例如:

#include <iostream>
using namespace std;


int max(int _a , int _b)
{
	return _a>_b?_a:_b;
}
int max(const int _a ,const int _b)

{
	return _a>_b?_a:_b;

}

void main()

{
	system("pause");
}

编译器将会提示如下错误:

dbd9f1bfe6fd4243718bdc16bc4f75a6.png

当重载的函数中有缺省参数的时候,还有种情况也会发生参数不明:

如以下代码,如果调用的函数为Test(‘A’)时,就会发生参数调用不明的情况,因为在调用的时候不写缺省参数,因此编译器认为以上声明的函数都有可能,所以就会发生参数调用不明确。

#include <iostream>
using namespace std;

void Test(char _a)

{
	cout<<_a<<endl;

}
void Test(char _a,int _b = 0)

{

	cout<<_a<<_b<<endl;
}

void main()
{
	Test('A');
	Test('A',10);

	system("pause");

}

当我们调用红色Test(‘A’)时,程序会报出如下错误:

8a7d3faa002308f76ff886c54efb1b19.png

当我们调用Test(‘A’,10)时,程序能够正确执行! 为什么?

函数重载解析:一个重载函数在被调用的时候,会根据实参来决定调用的哪一个函数。

函数重载之所以会报错,是因为:

  1. 根据实参不能匹配重载函数中的任何一个
  2. 根据实参能够匹配重载函数的2个或2个以上,导致了对于重载函数的调用不明确

函数重载解析的过程有三个步骤:

  1. 确定函数调用考虑的重载函数的集合,确定函数调用中实参表的属性。
  2. 从重载函数集合中选择函数,该函数可以在给出实参个数和类型的情况下,用函数调用中指定的实参进行调用。
  3. 选择与调用最匹配的函数。

函数参数传递中的内存管理

当我们在调用一个函数的时候,系统会在被调函数内部开辟形参类型所占用的内存空间,将实参的值存入到开辟的内存空间中。

当该函数结束的时候,系统分配的内存空间会自动收回。

在代码区键入如下代码,编译运行查看结果:

#include <iostream>

using namespace std;


int Test( int _iValue )

{
int iTemp = _iValue;

cout<<iTemp<<endl;
return iTemp+10;
}

void main()
{

cout<<Test(10)<<endl;

cout<<_iValue<<endl;    //错误的,无法访问Test函数的形参
cout<<iTemp<<endl;      //错误的,无法访问Test函数内部的变量


system("pause");

}

4f73190df3722b630b677bc8a118bf3f.png

439336430a63d76ece7dd73c527a4d2d.png

①本次学习了C++中的函数重载,并且分析了函数重载可能会发生的二义性,以及二义性的处理,使用好重载也是面向对象编程中的重点。

②函数在调用过程中内存如何进行分配。是后续学习的基础

③关于复杂函数参数类型(指针型参数、引用型参数、常量指针、常量引用等参数类型,我们将在学习了“指针”后为大家讲解)

学习资料领取:

https://pan.baidu.com/s/1VX_zb_eqWH_coos1ZB9QQw

提取码:w8st

学习从来都不是一个人的事,如果你感觉小编的这篇文章对你有帮助的话,可以关注小编首页和小编来一起学习C/C++语言,小编会持续更新后续的内容哦!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值