首页 > 编程知识 正文

c++重载(c读取txt文件存入数组)

时间:2023-05-04 12:54:19 阅读:99794 作者:1872

00-1010c可以在同一范围内定义多个函数和运算符,分别称为函数重载和运算符重载。通俗地说,同一个名字可以执行不同的功能,编译器通过参数类型匹配。

在C语言中,有编译时多态和运行时多态。源程序-编译-链接-可执行文件,其中源代码中的函数调用被解释为执行特定的函数代码块,称为函数名绑定。编译期间的绑定称为静态绑定。程序运行时完成的绑定称为动态绑定。

静态绑定:是指系统在编译时决定实现一个动作,需要在编译时知道调用函数的所有信息。静态绑定支持的多态变成了编译时多态(static多态),通过函数重载(包括运算符重载)和模板来实现。

动态绑定:是指系统在运行时动态实现一个动作。这样,直到程序运行时,我们才能确定调用哪个函数。动态绑定支持的多态变成了运行时多态(动态多态),通过虚函数实现。它的优点是更好的灵活性,问题抽象和易于程序维护。

重载概念

2.1功能过载概念

函数重载是指可以在同一范围内定义一组具有相同函数名和不同参数列表的函数。这些函数称为重载函数。虽然函数名相同,但是匹配不同的参数时,执行的内容是不同的。函数重载的准则如下:1)参数个数不同;2)不同的参数类型;3)参数的顺序不同。函数的重载至少满足其中一个条件,但需要注意的是,函数的返回值不能作为判断函数重载的标准。

当为同一个作用域中的单个名称指定两个或多个不同的声明时,该名称被称为重载。扩展而言,同一范围内声明相同名称但类型不同的两个声明称为重载声明。只能重载函数声明;不能从《ANSI C++ Standard. P290》重载对象和类型声明。——

重载函数通常用于命名一组功能相似的函数,减少了函数名的数量,避免了命名空间的污染,对程序的可读性有很大的好处。例如:

#包含iostream

使用命名空间标准;

无效最大值(整数a,整数b)

{

cout ' Max 1 ' endl

}

void Max(双a,双b)

{

cout ' Max 2 ' endl

}

void Max(双a、双b、双c)

{

cout ' Max 3 ' endl

}

int main()

{

Max(3,4);//调用void Max(int,int)

最大值(2.4,6.0);//调用void Max(doubleA double)

最大值(1.2,3.4,5);//调用void Max(双,双,双)

Max(1,2,3);//调用void Max(双,双,双)

//Max(3,1.5);//错误:歧义

返回0;

}可以看出,编译器可以根据调用Max函数的语句给出的参数个数和类型找到完美匹配的函数。但是,最后一个Max(3,1.5)的编译会出错,因为这两个参数是整数和实数。如果整数自动转换为实数,似乎应该调用函数void Max(double,double)。但是,如果实数的去尾自动转换为整数,那么调用void Max(int,int)似乎是合理的。

2.2编译器调用重载函数的指南

将所有同名函数作为候选函数;尝试寻找一个可行的候选函数;精确匹配实际参数;默认参数可以匹配实际参数;通过默认类型转换匹配参数;匹配失败;如果最终找到的可行候选函数不是唯一的,它将是模糊的,编译将失败。无法匹配所有候选项,函数未定义,编译失败。2.3函数重载满足函数的默认参数

例如:

#包含iostream

使用命名空间标准;

int func(int a,int

b, int c = 0) { return a * b* c; } int func(int a, int b) { return a + b; } int func(int a) { return a; } int main() { int c = 0; c = func(1, 2); // 存在二义性,调用失败,编译不能通过 printf("c = %dn", c); printf("Press enter to continue ..."); return 0; }

其中func(1, 2)存在二义性,可以看成缺省函数,可以调用int func(int a, int b)函数,也可以调用int func(int a, int b, int c = 0)函数。

2.4 函数重载和函数指针结合

当使用重载函数名对函数指针进行赋值时,根据重载规则挑选与函数指针参数列表一致的候选者,严格匹配候选者的函数类型与函数指针的函数类型。举个例子:

#include <iostream> using namespace std; typedef int(*PFUNC)(int a); // int(int a) int func(int x) { return x; } int func(int a, int b) { return a + b; } int func(const char* s) { return strlen(s); } int main() { int c = 0; PFUNC p = func; c = p(1);//调用int func(int x) printf("c = %dn", c); printf("Press enter to continue ..."); return 0; }

2.5 引入函数重载的原因

在C语言中没有重载机制,需要对具有不同参数类型或不同参数个数,但具有同一种功能的函数定义多个名称,对编程来说比较麻烦。类的构造函数跟类名相同。如果没有函数重载机制,要想实例化不同的对象,那是相当的麻烦!操作符重载,本质上就是函数重载,它大大丰富了已有操作符的含义,方便使用,如+可用于连接字符串等!

2.6 C++是如何做到函数重载的

int max(int a,int b) 映射为_Z3maxii、double max(double a,double b) 映射为_Z3maxdd。当发生函数调用时,编译器会根据传入的实参去逐个匹配,以选择对应的函数,如果匹配失败,编译器就会报错,这叫做重载决议(Overload Resolution)。不同的编译器有不同的重命名方式,同时函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。

2.7 编译器解析重载函数调用过程

编译器实现调用重载函数解析机制的时候,肯定是首先找出同名的一些候选函数,然后从候选函数中找出最符合的,如果找不到就报错。下面介绍一种重载函数解析的方法:编译器在对重载函数调用进行处理时,由语法分析、C++文法、符号表、抽象语法树交互处理,交互图大致如下:

编译器解析重载函数调用过程

这个四个解析步骤所如下:

由匹配文法中的函数调用,获取函数名;获得函数各参数表达式类型;语法分析器查找重载函数,符号表内部经过重载解析返回最佳的函数;语法分析器创建抽象语法树,将符号表中存储的最佳函数绑定到抽象语法树上。

运算符重载

3.1 运算符重载概念

与函数重载类似,运算符也可以重载,如图所示是运算符重载的例子:

运算符重载例子

重载的运算符是带有特殊名称的函数,函数名是由关键operator和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。例如:

Box operator+(const Box&);

声明加法运算符用于把两个Box对象相加,返回最终的Box对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果定义上面的函数为类的非成员函数,那么需要为每次操作传递两个参数,例如:

Box operator+(const Box&, const Box&);

举个例子, 对象作为参数进行传递,对象的属性使用 this 运算符进行访问:

#include <iostream> using namespace std; class Box { public: double get_volume(void) { return length * width * height; } void set_param(double len, double wid, double hei) { length = len; width = wid; height = hei; } // 重载 + 运算符,用于把两个 Box 对象相加 Box operator+(const Box& b) { Box box; box.length = this->length + b.length; box.width = this->width + b.width; box.height = this->height + b.height; return box; } private: double length; // 长度 double width; // 宽度 double height; // 高度 }; // 程序的主函数 int main() { Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box Box Box3; // 声明 Box3,类型为 Box double volume = 0.0; // 把体积存储在该变量中 Box1.set_param(6.0, 7.0, 8.0); Box2.set_param(12.0, 13.0, 14.0); // Box1 的体积 volume = Box1.get_volume(); cout << "Volume of Box1 : " << volume << endl; // Box2 的体积 volume = Box2.get_volume(); cout << "Volume of Box2 : " << volume << endl; // 把两个对象相加,得到 Box3 Box3 = Box1 + Box2; // Box3 的体积 volume = Box3.get_volume(); cout << "Volume of Box3 : " << volume << endl; return 0; }

3.2 可重载运算符/不可重载运算符

可重载运算符和不可重载运算符

3.3 运算符重载准则

只能对已有运算符进行重载,不允许用户自己定义新的运算符。运算符重载是针对新类型数据的实际需要,不建议改变原运算符的含义。(例如将+运算符重载为进行减法运算)。运算符重载不能改变运算符的操作对象(即操作数)的个数。运算符重载不能改变运算符原有的优先级。运算符重载不能改变运算符原有的结合性。运算符重载函数的参数至少有一个是类对象(或其引用)。目的是防止用户修改用于标准类型数据的运算符性质。运算符重载函数可以是普通函数、类成员函数、类的友元函数。赋值运算符“="可以不必用户进行重载。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。