51购物网官方网站,wordpress数据库调用文章,我的网站突然打不开了,国外服务器购买推荐一、多态引入 多态按字面的意思就是多种形态。当类之间存在层次结构#xff0c;并且类之间是通过继承关联时#xff0c;就会用到多态。 C 多态意味着调用成员函数时#xff0c;会根据调用函数的对象的类型来执行不同的函数。
根据代码#xff0c;引入多态的概念#xff1…一、多态引入 多态按字面的意思就是多种形态。当类之间存在层次结构并且类之间是通过继承关联时就会用到多态。 C 多态意味着调用成员函数时会根据调用函数的对象的类型来执行不同的函数。
根据代码引入多态的概念
#include iostream
using namespace std;//定义一个成人类
class Person {
public:virtual void BuyTicket() { cout 成人买票-全价 endl; }
};//定义一个学生类
class Student : public Person {
public:virtual void BuyTicket() { cout 学生买票-半价 endl; }
};void Func(Person p)
{p.BuyTicket();
}
int main()
{Person ps; //成人对象Student st; //学生Func(ps); // void Func(Person p) 参数传参函数调用Func(st); // void Func(Person p) 参数传参函数调用return 0;
}执行结果可以看出根据对象的不同调用出来不同的结果 多态的概念通俗来说就是多种形态 具体点就是去完成某个行为当不同的对象去完成时会 产生出不同的状态 。 修改上面的代码观察结果
#include iostream
using namespace std;class Person {
public://修改前virtual void BuyTicket() { cout 成人买票-全价 endl; }void BuyTicket() { cout 成人买票-全价 endl; }
};class Student : public Person {
public://修改前virtual void BuyTicket() { cout 学生买票-半价 endl; }void BuyTicket() { cout 学生买票-半价 endl; }
};void Func(Person p)
{p.BuyTicket();
}
int main()
{Person ps;Student st;Func(ps);Func(st);return 0;
}我们去掉virtual 关键字之后看到结果都是调用父类的BuyTicket()函数。 原因分析student类继承person类两个类里面的BuyTicket()函数函数名一样构成重定义1.函数名相同 2.两个函数分别在父子类的作用域里 3. 父子类的同名函数不构成重写所以子类对象赋值给父类对象的时候会将子类对象中的父类切出来自然而然调用的是父类的成员函数
我们再修改代码思考结果
#include iostream
using namespace std;class Person {
public:virtual void BuyTicket() { cout 成人买票-全价 endl; }
};class Student : public Person {
public:virtual void BuyTicket() { cout 学生买票-半价 endl; }
};void Func(Person p) //修改前Person p
{p.BuyTicket();
}
int main()
{Person ps;Student st;Func(ps);Func(st);return 0;
}这个结果的产生原因和上面的原因是一致的父类赋值给父类对象自然调用父类的成员函数、子类对象赋值给父类对象造成“切片”将子类中的父类那一部分切出去让父类对象调用
再修改代码看结果
#include iostream
using namespace std;class Person {
public:virtual void BuyTicket() { cout 成人买票-全价 endl; }
};class Student : public Person {
public:virtual void BuyTicket() { cout 学生买票-半价 endl; }
};void Func(Person* p) //修改前Person p
{p-BuyTicket();
}
int main()
{Person ps;Student st;Func(ps); //修改前 Func(ps);Func(st); //修改前 Func(st);return 0;
}使用指针的时候又根据指向对象的不同调用出不同的结果
根据上面的代码结果我们可以大概感知到多态就是根据不同继承关系的类对象调用同一函数时产生了不同的行为。那么产生多态的条件是什么呢 文章目录 一、多态引入修改上面的代码观察结果我们再修改代码思考结果再修改代码看结果 二、多态构成的条件回顾上面的代码感受多态的条件析构函数的重写-析构函数名统一会被处理成destructor()C11 新语法override 和 final抽象类1、概念2、 抽象类代码感知 总结 二、多态构成的条件
重写的概念 两个函数分别在子类和父类的作用域中函数名 / 返回值 / 参数都必须相同两个函数必须是虚函数 被virtual 修饰的类成员函数成为虚函数注意参数只看类型是否相同不看缺省值 多态构成的条件 需要在继承中使用必须使用父类的引用或者指针调用虚函数被调用的函数必须是虚函数且子类必须对父类的虚函数进行重写 回顾上面的代码感受多态的条件
#include iostream
using namespace std;
class Person {
public://父类的虚函数virtual void BuyTicket() { cout 成人买票-全价 endl; }
};class Student : public Person {
public://子类 重写 父类的虚函数重写函数名、返回值、参数必须相同virtual void BuyTicket() { cout 学生买票-半价 endl; }
};void Func(Person* p)
{p-BuyTicket();
}
int main()
{Person ps;Student st;Func(ps);Func(st);return 0;
}这时候指针p它指向什么类型就调用该类型的对象里面的成员 析构函数的重写-析构函数名统一会被处理成destructor()
只有子类 Student 的析构函数重写了 Person 的析构函数下面的 delete 对象调用析构函 数才能构成多态才能保证 p1 和 p2 指向的对象正确的调用析构函数。 函数名处理成destructor() 才能满足多态 如果父类的析构函数为虚函数此时子类析构函数只要定义无论是否加virtual关键字 都与父类的析构函数构成重写虽然父类与子类析构函数名字不同。虽然函数名不相同 看起来违背了重写的规则其实不然这里可以理解为编译器对析构函数的名称做了特殊处 理编译后析构函数的名称统一处理成destructor。
class Person {
public:virtual ~Person() {cout ~Person() endl;}
};
class Student : public Person {
public:virtual ~Student() { cout ~Student() endl; }
};
int main()
{Person* p1 new Person;Person* p2 new Student;delete p1;delete p2;return 0;
}所以当父类的指针指向子类的对象时一定需要将父类的析构函数写成虚函数如果不定义成虚函数那么delete p的时候就会只父类的析构函数切片不会调用子类的析构函数造成内存泄漏
C11 新语法override 和 final
final修饰虚函数表示该虚函数不能再被重写 override: 检查子类虚函数是否重写了父类某个虚函数如果没有重写编译报错 抽象类
1、概念
在虚函数的后面写上 “ 0” 则这个函数为纯虚函数包含纯虚函数的类叫做抽象类也叫接口类抽象类不能实例化出对象。子类继承后也不能实例化出对象只有重写纯虚函数子类才能实例化出对象。纯虚函数规范了子类必须重写另外纯虚函数更体现出了接口继承。
2、 抽象类代码感知
#include iostream
using namespace std;class Car
{
public:virtual void Drive() 0;// // 实现没有价值因为没有对象会调用他// /*virtual void Drive() 0// {// cout Drive() endl;// }*/
};
class Benz :public Car
{
public:virtual void Drive() //重写父类的纯虚函数{cout Benz-舒适 endl;}
};
class BMW :public Car
{
public:virtual void Drive() //重写父类的纯虚函数{cout BMW-操控 endl; }
};
void Test()
{Car* pBenz new Benz;pBenz-Drive();Car* pBMW new BMW;pBMW-Drive();
}
int main()
{Test();return 0;
}总结
今天我们熟悉了多态的构成条件以及多态的使用下一次我们详细聊聊多态的原理感知一下为什么会出现这样的结果编译器是怎么做得