主备网站服务器自动切换 win2003,免费的个人的网站,中国建设资格注册中心网站,政务服务平台文章目录一、多态是什么#xff1f;二、使用步骤2.1. 静态多态2.1.1 函数重载2.1.2 模板2.2.动态多态2.2.1 示例2.2.2 原理分析总结一、多态是什么#xff1f;
多态是面向对象的语言中都必须掌握的特性#xff0c;其概念简单讲就是对同一种特性的方法有不同的实现功能…
文章目录一、多态是什么二、使用步骤2.1. 静态多态2.1.1 函数重载2.1.2 模板2.2.动态多态2.2.1 示例2.2.2 原理分析总结一、多态是什么
多态是面向对象的语言中都必须掌握的特性其概念简单讲就是对同一种特性的方法有不同的实现功能例如玩手机这个方法有人玩抖音有人玩LOL等等种不同的应用形式。 多态可以按照绑定分为静态多态和动态多态。 绑定是指函数体与函数调用完成关联的过程。 静态多态是指在程序编译期间就完成一般通过函数重载和模板来完成会根据函数实参的类型或个数来选择那个函数来实现。 动态多态是指在程序编译后完成的联编通过虚方法的形式完成根据引用对象的实际类型调用相应的方法。其原理就是用父类的虚函数指针去调用子类中被重写的方法。
二、使用步骤
2.1. 静态多态
2.1.1 函数重载
下面为构造函数重载示例
class Cat
{
public:Cat(){cout 喵是无参构造函数 endl;}Cat(string name){Name name;cout 喵是有参构造函数 endl;}//用于拷贝c的属性值用常量引用的方式进行Cat(const Cat c){Name c.Name;cout 喵是拷贝构造函数 endl;}~Cat(){cout 喵是析构函数 endl;}string Name;//咪咪名字
};void FindName()
{//括号法Cat cat1;//用默认构造函数时不能加括号否则编译器会当作函数声明。Cat cat2(cat1);//拷贝构造函数调用Cat cat3(小300);//有参构造函数调用。Cat cat4(cat3);//拷贝构造函数调用cout 第一个猫的名字是 cat1.Name endl;cout 第二个猫的名字是 cat2.Name endl;cout 第三个猫的名字是 cat3.Name endl;cout 第四个猫的名字是 cat4.Name endl;
}2.1.2 模板
模板在C中分为类模板和函数模板用template修饰和泛型的概念很相似。
类模板是通过建立一个通用类其中的数据成员、成员函数的返回值类型和形参类型不进行具体指定用一个虚拟的类型声明。在使用类模板定义对象时系统会实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。
函数模板也需声明一个模板类名然后在函数形参中声明一个模板类对象在进行函数调用时会根据实参的类型来覆盖模板类。
函数模板调用规则 1.如果函数模板和普通函数都可以实现功能的话优先调用普通函数。 2.可以通过空模板参数列表来强制调用函数模板。 3.函数模板可以发生重载。 4.如果函数模板可以产生更好的匹配,优先调用函数模板。
类模板和函数模板的区别 1类模板没办法对声明的模板类对象进行自动推导类型必须用指定类型函数模板可以。 2类模板在模板参数声明时可以有默认参数类型比如在声明构造函数时一个形参为模板类型一个为int类型。
类模板
#include iostream
#includestring
using namespace std;templateclass T1, class T2class Person
{
public:Person(T1 name, T2 age){this-m_age age;this-m_name name;}void showPerson(){cout m_name m_age endl;}private:T1 m_name;T2 m_age;
};int main()
{Personstring, int p(张三, 1);p.showPerson();system(pause);return 0;
}函数模板
#include iostream
using namespace std;templateclass T//T的类型需要一致选择排序
void Sort(T arr[], int l)
{for (int i 0; i l; i){int max i;for (int j i 1; j l; j){if (arr[max] arr[j]){max j;}}if (max ! i){T temp arr[max];arr[max] arr[i];arr[i] temp;}}
}int main()
{int Array[] {1,4,35,24,213,2132};int num sizeof(Array) / sizeof(int);Sort(Array, num);//Sort(Array, num);//空模板参数列表for(int i 0; i num; i){cout Array[i] endl;}system(pause);return 0;
}2.2.动态多态
动态多态需满足以下条件 1.类之间存在继承关系 2. 调用函数的对象必须是指针或者引用。 3.子类重写父类函数(函数返回值、名称和参数列表相同)
2.2.1 示例
#includeiostream
using namespace std;class Student
{
public://虚函数virtual void play(){cout 我在玩手机 endl;}//纯虚函数纯虚函数的类为抽象类类无法实例化/*virtual void play() 0;*///父类写虚析构函数virtual ~Student(){}
};class Student1 :public Student
{
public:Student1(string app){APP new string(app);}void play(){cout 我在刷 *APP endl;}//如果没有在堆区开辟内存的化不用写~Student1(){if (APP ! NULL){delete APP;APP NULL;}}private:string *APP;
};class Student2 :public Student
{
public:Student2(string app){APP new string(app);}void play(){cout 我在玩 *APP endl;}~Student2(){if (APP ! NULL){delete APP;APP NULL;}}
private:string* APP;
};int main()
{//父类指针在调用自身的析构函数时不会调用子类的析构从而造成内存泄露所以要改为虚析构的方法。Student* s1 new Student1(抖音);s1-play();delete s1;Student* s2 new Student2(LOL);s2-play();delete s2;
}2.2.2 原理分析
同样可以使用开发者工具进行分析。 其中vfptr指的是虚函数指针vftable指的是虚函数表父类子类中均存在虚函数指针和表其中指针指向虚函数表。在进行虚函数的重写时就会产生子类的虚函数指针通过声明父类指针或引用调用函数时就会覆盖vftable中类名指向对应子类中的重写方法。 总结
多态的概念使C的编程非常灵活需要特别注意开闭原则和内存管理。