前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++基础——C++面向对象之重载与多态基础总结(函数重载、运算符重载、多态的使用)

C++基础——C++面向对象之重载与多态基础总结(函数重载、运算符重载、多态的使用)

作者头像
Winter_world
发布2023-03-09 20:51:49
5770
发布2023-03-09 20:51:49
举报

原文链接:https://cloud.tencent.com/developer/article/2237210

目录

0 引言

1 重载

1.1 函数重载

1.2 运算符重载

2 多态

3 总结

0 引言

        上一次博文讲解了C++的类和对象,以及继承的特征,本次博文总结下C++面向对象的另外两个关键特征——重载与多态。

1 重载

        C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。

        当调用一个重载函数或重载运算符时,编译器通过把所使用的参数类型与定义中的参数类型对比,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。

1.1 函数重载

        在同一作用域内,可声明多个功能类似的同名函数,这些同名函数的形参(参数个数、类型或者顺序)必须不同,我们不能仅通过返回类型的不同来重载函数。 Qt源码中运用了大量的函数重载,不仅在 C++中,在其他语言如Java等也有, 因为需要不同,所以有重载各种各样的函数。

下面做个示例程序,说明函数重载的使用方法。

        以之前博文写的人 这个类为例,打印这个人的体重,分别以整数和小数记录,并分别打印,这个通过函数重载实现就很容易。

新建一个07_func_overload目录,其下新建一个07_func_overload.cpp文件,代码如下:

代码语言:javascript
复制
#include <iostream>
#include <string>
using namespace std;

class People
{
public:
	string name;
	void getWeight(int weight){
		cout << "weight:" << weight << "Kg" << endl;
	}

	void getWeight(double weight){
		cout << "weight:" << weight << "Kg" << endl;
	}

};

int main()
{
	People people;
	people.name = "小芳";
	people.getWeight(90);
	people.getWeight(90.5);
	return 0;
}

        程序中在People类中定义了两个getWeight()方法,一个参数为int,另一个为double,这就构成了函数重载,在main函数中传入不同的参数,程序就会匹配不同的重载函数。

编译程序,运行结果如下:

        以上简单的实例,我们知道了函数重载的用法,有时需要避免用户传入的参数类型不在重载函数里,编译器报错这种情况,这时可以多写几个重载函数,设置多个参数类型。

1.2 运算符重载

        运算符重载,实质是函数重载或函数多态,目的在于让人能够用同名的函数来完成不同的基本操作。要重载运算符,需要使用被称为运算符函数的特殊函数形式, 重载运算符的格式如下:

代码语言:javascript
复制
<返回类型说明符> operator <运算符符号>(<参数表>)
{
    <函数体>
}

可重载的运算符列表:

不可重载的运算符列表:

实际上重载运算符在实际中应用并不多,下面以“+”为例,了解下这种思想。

        下面举个例子,对象作为参数进行传递,对象的属性使用 this 运算符进行访问。 声明加法运算符用于把两个People 对象体重相加,返回最终的 People 对象,然后得到第三个People 对象的体重。

新建一个08_operator目录,其下新建一个08_operator.cpp,代码如下:

代码语言:javascript
复制
#include <iostream>
#include <string>
using namespace std;

class People
{
public:
	int weight;
	People operator+(const People &p){
		People people;
		people.weight = this->weight + p.weight;
		return people;
	}
};

int main()
{
	People people1;
	People people2;
	People people3;
	people1.weight = 10;
	people2.weight = 40;
	people3 = people1 + people2;
	cout << "people3 weight :" << people3.weight << "Kg" << endl;
	return 0;
}

        程序中,重载“+”运算符,注意函数必须与类名同名, 把People对象作为传递, 使用this 运算符进行访问,然后返回一个 People对象。可见重载运算法可以将两个对象相加,在普通的运算符+中,这个做不到的,所以重载运算法的意义就体现在此。

编译程序,运行结果:

2 多态

        C++中多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数,形成多态必须具备三个条件:

  • 1)必须存在继承关系;
  • 2)继承关系必须有同名虚函数;
  • 3)存在基类类型的指针或者引用,通过该指针或引用调用虚函数。

虚函数:指的是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。 虚函数声明如下: virtual ReturnType FunctionName(Parameter) 虚函数必须实现,如果不实现,编译器将报错。

纯虚函数:若在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。 纯虚函数声明如下:

virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。

包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。

下面通过实例说明多态的使用。

新建一个09_polymorphism目录,其下新建一个09_polymorphism.cpp,代码如下:

代码语言:javascript
复制
#include <iostream>
#include <string>
using namespace std;

//动物类
class Animal
{
public:
	virtual void speak(){
		cout << "Animal的speak()方法" << endl;
	}
};

//定义一个People类,继承Animal
class People : public Animal
{
public:
	void speak(){
		cout << "People的speak()方法" << endl;
	}
};

//定义一个Dog类,继承Animal
class Dog : public Animal
{
public:
	void speak(){
		cout << "Dog的speak()方法" << endl;
	}
};

int main()
{
	//声明一个 Animal 的指针对象,并没有实例化
	Animal *animal; 
	People people;
	Dog dog;
	//存储dog和people对象的地址,并调用speak()方法
	animal = &people;
	animal->speak();
	
	animal = &dog;
	animal->speak();

	return 0;
}

        新定义的People和Dog类,都继承了Animal基类,可见基类Animal中的speak()方法前加了virtual关键字,变成了虚函数;虚函数是C++中实现多态的机制,核心就是通过基类访问派生类定义的函数;

        上面的实例是基类 Animal 声明了一个指针 animal。然后通过基类的指针来访问 Dog 类对象与 People 类的对象的 speak()方法,前提是基类的 speak()方法必须声明为虚函数,且基类和派生类中定义的方法名要相同,否则,基类的指针将访问到基类自己的speak()方法。

编译程序,运行如下:

3 总结

        本次博文总结了C++的面向对象特征,重载和多态,重载是在同一作用域内,可声明多个功能类似的同名函数,这些同名函数的形参必须不同,可以根据实际需要,重载各种各样的函数;多态的实现机制是通过虚函数,核心就是通过基类访问派生类定义的函数;有了多态,我们可以在程序中任意点可以根据所调用的对象类型来选择调用的函数,实现动态链接,或后期绑定的效果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0 引言
  • 1 重载
    • 1.1 函数重载
      • 1.2 运算符重载
      • 2 多态
      • 3 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档