C++基础入门(下)
-
函数重载
函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的 形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题
代码演示:
#include<iostream> using std::cout; using std::endl; int Add(int a, int b) { return a + b; } double Add(double a, double b) { return a + b; } int main() { cout << Add(1,2) << endl; cout << Add(2.0,2.0) << endl; }
输出结果为:3,4
注意:这里并没有因为两个函数名都是Add而导致报错,但是要注意函数的重载是和函数的参数有关,和返回值时无关的,而且上述所说的函数参数的顺序不同可以重载,指得并不是参数的顺序,而是参数类型的顺序
代码演示:
#include<iostream> using std::cout; using std::endl; int Add(int a, int b) { return a + b; } double Add(int b, int a) { return a + b; } int main() { cout << Add(1,1) << endl; cout << Add(2,2) << endl; }
注意:上述代码是错误的,会导致重命名的情况,因为参数是完全相同的,那么为什么C++可以支持函数重载而C语言却并不行呢?因为C++的函数名修饰规则利用了参数,而C语言没有
-命名规则(name Mangling)
Name Mangling是一种在编译过程中,将函数、变量的名称重新改编的机制,简单来说就是编译器为了区分 各个函数,将函数通过某种算法,重新修饰为一个全局唯一的名称。
代码演示:
#include<stdio.h> int Add(int a, int b); int main() { Add(1,1); }
注意:由于Add函数只有声明没有定义,所以就没有给Add开辟空间,所以在调用的时候就找不到Add函数的地址,会报链接错误,我们可以明显的看到,C语言对Add函数的命名规则是只是在它的前面加上一个下划线,这就导致了当有两个函数名相同的函数存在时,在调用的时候,都是以"_函数名"的形式来寻找的,分不清具体是哪个函数,就会出问题
如图所示:
我们再来看看c++的情况,代码演示:#include<iostream> using std::cout; using std::endl; int Add(int a, int b) { return a + b; } double Add(int a, double b) { return a + b; } int main() { cout << Add(1, 1) << endl; cout << Add(1, 1.0) << endl; }
注意:
1.写好代码后编译,指令为:gcc 创的文件名
如图:
2.转到反汇编,指令为:objdump -s 生成的可执行文件名
如图:
3.转到反汇编后,观察两个函数体部分,可以看出两个函数的命名是不同的,在Linux下,函数名的命名规则是:_z+函数名的字母个数+函数名+函数形参类型的首字母
如图:
-
auto关键字(C++11)
-.auto简介
>在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有 人去使用它,所以在C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型 指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得早期auto一直没有人去使用原因:局部变量被默认为auto类型代码演示:
#include<iostream> using std::cout; using std::endl; double Founc() { return 4.0; } int main() { int a = 1; auto b = a; auto c = 'a'; auto d = Founc(); cout << a << endl; cout << b << endl; cout << c << endl; cout << d << endl; //auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化 }
输出结果为:
注意:使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类 型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为 变量实际的类型。-auto的使用细则
1.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&,但是用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
代码演示:
#include<iostream> using std::cout; using std::endl; int main() { int a = 1; auto b = &a; auto* c =&a; auto& d = a; cout << typeid(b).name() << endl; cout << typeid(c).name() << endl; cout << typeid(d).name() << endl; }
输出结果为:
2.当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对 第一个类型进行推导,然后用推导出来的类型定义其他变量。
代码演示:
#include<iostream> using std::cout; using std::endl; int main() { auto a = 1, b = 2; auto c = 'c', d = 5;//此时会报错 }
-auto不能推导的场景
1. auto不能作为函数的参数
void founc(auto a) {} //此时代码会报错,因为auto无法推导出它是什么类型
2. auto不能直接用来声明数组
void founc() { int a=[1,2,3,4]; auto b[4]=a; //此时代码就会报错 }
3. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法 (所以在不同时间发行的编译器上,可能无法使用auto)
4. auto在实际中常见的优势用法就是跟C++11提供的新式for循环,还有lambda表达式等 进行配合使用。
5.auto不能定义类的非静态成员变量
6. 实例化模板时不能使用auto作为模板参数