**
重载函数
重载函数:它属于C++的一种特殊函数,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
利用实例来进行详细说明:
问题一:上面给出Test两个函数能否构成重载?
void TestFunc(int a = 10)//无缺省
{
cout<<"void TestFunc(int)"<<endl;
}
void TestFunc(int a )//有缺省
{
cout<<"void TestFunc(int)"<<endl;
}
void main()
{
TestFunc(100);//二义性
TestFunc();
}
分析:当主函数去调用Test函数时,上面两个函数都可以被主函数调用,此时会发生二义性,所以不能实现函数重载。只依靠有无缺省(默认值)不能构成重载。
答案:NO
C语言不能构成函数重载的原因:c语言在c编译器中改写函数命名时,统一形式是在原来命名前加下划线,所以无法对其进行区别,在调用时候不具有唯一性,因此不能构成重载。例如 :TestFunc(); 改写后的名称为—TestFunc();
C++中能构成函数重载的原因:c++重载时,在编译器改写函数名称时,会把返回值类型、参数列表类型和个数全部考虑进去,因此改写的名称具有唯一性,在调用时可以根据改写后的名称找到对应的函数进行函数重载。
问题二:下面这种情况可以实现重载吗?
int TestFunc(int a )
{
cout<<"void TestFunc(int)"<<endl;
}
double TestFunc(int a )
{
cout<<"void TestFunc(int)"<<endl;
}
分析:在调用函数时当函数名和参数类型和个数有区别时,才能构成重载条件,跟返回值类型无关。上面两个函数除了返回值类型不同,函数名和参数类型都是一致的,在调用时无法确定调用对象,不符合函数重载的条件。因此不能依靠返回值类型不同构成函数重载。
答案:NO
**
引用
引用:引用是给已有的变量取得别名,编译器不会为引用变量开辟新的内存空间,它和“原主人”(也就是引用的变量)共用同一块内存空间。
实例走一波:李逵,在家称为“铁牛”,江湖人称“黑旋风”
引用格式:
类型& 引用变量名(对象名) = 引用实体;
void main()
{
int a = 10;
int &b = a;//b为a的引用,引用的本质是指针
cout<<"b = "<<b<<endl;
}
特别说明:
(1)没有空引用,不能给不存在的变量取别名;
(2)引用不开辟新空间;
(3)同一变量可以有多个引用,别名也可引用;
(4)引用在定义时必须初始化;
(5)引用一旦引用一个实体,再不能引用其他实体
void TestRef()
{
int a = 10;
// int& ra; // 该条语句编译时会出错
int& ra = a;
int& rra = a;
printf("%p %p %p\n", &a, &ra, &rra);
}
数组、指针和结构体的引用要特别注意:
void main()
{
int ar[10]={1,2,3,4,5,6,7,8,9,10};
int &br = ar;//该条语句编译时会出错
int (&br)[10] = ar;//数组引用格式要完整,为了体现引用,要添加小括号提高符号优先级
int *ptr = &a;//指针的引用
int* &q = ptr;//q是ptr的一个引用(别名)
}
struct Student
{
char name;
int age;
char sex[5];
}
void main()
{
Student stu;
Student &rstu = stu;//结构体引用
}
常引用
void main()
{
int a = 10;
const int &b = a;//常引用
a = 100; //可修改a的值
b = 1000;//该条语句编译时会出错,a是常变量,b是a的常引用,常引用不能修改a的数值
}
a自己修改没问题,b不能修改a
void Swap(int &x, int &y)//这里要注意,x是a的引用,y是b的引用。传值时候要传地址,如果不加引用,x,y是临时变量,子函数内交换后会被释放,跟主函数无关。一定要把x和y的地址传到主函数内,在进行传值,也就是常说的要传递实参,就要传递地址。
{
int tmp = a;
a = b;
b = tmp;
}
void main()
{
int a = 100;
int b = 10;
cout<<a<<" "<<b<<endl;
Swap(a,b);
cout<<a<<" "<<b<<endl;
}
引用当作函数参数时,主要是提高程序的执行效率,因为它不开辟新的空间。
引用返回:如果使用引用返回时,编译器就不产生中间的无名变量,当函数空间运行结束后会被释放,返回值就会出错。
也就是说如果函数返回时,出了函数作用域,如果返回对象还未还给系统,则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。
传值、传引用效率比较:以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。而引用因为不开辟新的空间,几乎不会消耗时间,但是在使用引用时,要注意函数的作用域,如果是局部变量随后要释放的话,就不能使用引用,如果是全局变量不被释放,就可以使用。
引用的实质时指针,但它们也存在不同点:
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
- 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
- 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全