函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或
类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
对于c语言
是不允许重名函数的存在的,当函数名字相同时,就会报错。但是对于 c++ 可以。
因为C语言
是根据函数名来去找函数的,可以简单的理解为C语言
函数名就是地址
当函数重载条件满足如下三条时,则可以构成函数重载:
1.参数类型不同
2.参数个数不同
3.参数类型顺序不同
4、仅仅返回类型不同不足以称为函数重载的重载
5、需要在同一作用域下
int add(int a, int b)
{
return a + b;
}
void add(int a, float b)
{
cout << "add(int a,float b)" << endl;
}
void add(float a, int b)
{
cout << "add(float a,int b)" << endl;
}
float add(float a, float b)
{
return a + b;
}
对于函数重载后的函数,执行会不会变慢?不会,因为不是在运行时匹配,而是在编译时。
编译时如何进行识别?
对于C语言来说,就是依靠函数名去找函数的,如果函数名相同,则会冲突,因为不知道找哪个
对于C++来说,是通过函数名+参数类型+参数个数+参数顺序
引用的基本概念
使用引用的好处
引用与指针的比较
常量引用
引用作为返回类型
我们发现a和b不仅值相等,连地址也是相同的。而这就说明,b 就是 a ,在语法层面上,这里 b 并不是开辟的新空间,而是对原来的 a 取了一个新名称,叫做 b
相当于一块空间有多个名字一样,都是指向这块空间的
而如果这时候对 a 或 b 任意一个修改,那么 a 和 b 都会发生修改。
int main()
{
int a = 10;
int& b = a;
int c = 20;
b = c;
return 0;
}
那么这样又是什么意思呢
b引用了a,然后b=c是将c的值赋值给b
这就说明引用一旦引用一个实体,就不能引用其他实体,引用是不会发生改变的
引用作为函数返回值
在Test函数当中定义了一个n,然后返回n的别名
在main函数当中用ret接受n的值
再打印ret,结果一直都是1
虽然Test()那块函数栈帧已经被销毁,但是我们使用int ret接受的n的值,并不是n
所以ret就是1
#include
using namespace std;
int& Test()
{
int n = 1;
return n;
}
int main()
{
int ret = Test();
cout << ret << endl;
cout << ret << endl;
cout << ret << endl;
cout << ret << endl;
return 0;
}
然后我们将ret换为int & 来接受
这时候ret就是n的别名
n出了函数作用域就销毁了,函数栈帧销毁了,但是里面的东西还没有被覆盖,传引用返回给ret的话,ret话会去访问原来n那块空间的值
函数调用先传参,所以调用cout的时候,ret先去访问n原来的那块空间,得到n值之后再给cout
cout函数会建立一块函数栈帧空间在原来的Count上,所以打印出1
第二次调用cout的时候,ret再去访问n的时候,原来的空间已经被破坏了,所以这一次打印出来的是随机值
#include
using namespace std;
int& Test()
{
int n = 1;
return n;
}
int main()
{
int& ret = Test();
cout << ret << endl;
cout << ret << endl;
cout << ret << endl;
cout << ret << endl;
return 0;
}
所以说如果用引用做返回值的话就需要确保返回的东西除了作用域是还存在的
#include
using namespace std;
int main()
{
int a = 1;
int& b = a;
const double& d = a;
const int& c = 1;
return 0;
}
对于类型转换,会先产生一个临时变量
然后临时变量具有常性,所以不可以被修改
所以double &d=a; 实际上并不是d去引用a
而是d去引用一个临时变量,所以需要+const去修饰
#include
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; } // 拷贝
// 引用返回
A& TestFunc2() { return a; } // 不拷贝
void TestReturnByRefOrValue()
{
// 以值作为函数的返回值类型
size_t begin1 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc1();
size_t end1 = clock();
// 以引用作为函数的返回值类型
size_t begin2 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc2();
size_t end2 = clock();
// 计算两个函数运算完成之后的时间
cout << "TestFunc1 time:" << end1 - begin1 << endl;
cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
int main()
{
TestReturnByRefOrValue();
return 0;
}
由于传值返回要拷贝,所以当拷贝量大,次数多时,比较耗费时间;而传引用返回就不会,因为返回的就是别名
定义和初始化:
*
来声明,可以指向不同的对象。&
来声明,必须在初始化时绑定到一个已存在的变量。空值(Null):
变量绑定:
空间占用:
空间操作:
*
访问所指的内存地址的值。空间限制和安全性:
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}