多态、纯虚函数(抽象类)和虚析构
作者:互联网
一.多态
多态:
1.静态多态:函数重载和运算符重载 //编译阶段确定函数地址
2.动态多态:派生类的虚函数实现运行时多态 //运行阶段确定函数地址
动态多态满足条件1.继承关系 2.子类重写父类虚函数
重新 :函数返回值类型 函数名 参数列表完全相同
动态多态的使用:父类的指针或引用指向子类对象
//多态 //动态多态满足条件1.继承关系 2.子类重写父类虚函数 //重新 :函数返回值类型 函数名 参数列表完全相同 class Animal { public: void speak() //添加virtual 虚函数 子类重写 { cout << "说话" << endl; } }; class Cat :public Animal { public: void speak() { cout << "猫说话" << endl; } }; //执行说话 //地址早绑定,在编译阶段确定了函数地址 所有执行动物说话 void Aspeak(Animal& animal) // Animal &animal=cat; 父类引用指向子类对象 { animal.speak(); } int main() { Cat cat; Aspeak(cat); return 0; }
二.纯虚函数
在多态中,父类的虚函数实现是无意义的(通常调用子类重写内容),因此可以使用纯虚函数。
纯虚函数:virtual 返回值类型 函数名(参数列表)= 0
当类中有纯虚函数称为抽象类。
抽象类特点:
1.无法实例化对象(在class base中无法使用base b; / new base;创建对象)
// new返回的是该类型的指针 Base * p=new Son;
2.抽象类的子类 必须要重写父类中的纯虚函数,否则无法创建
class Base//类中有纯虚函数则称为抽象类 { public: virtual void func() = 0;//纯虚函数 }; class Son :public Base { //2.抽象类的子类 必须要重写父类中的纯虚函数,否则无法创建 //Son s;//无法创建 virtual void func() { cout << "你好" << endl; } }; int main() { //1.抽象类无法实例化对象 //Base b; //new Base; Base* base = new Son; base->func();
三.纯虚析构
在使用时若子类有属性开辟到堆区,父类指针无法释放子类对象则需要使用虚析构
虚析构和纯虚析构:
解决父类指针释放子类对象
都具有函数的实现
纯虚析构不能实例化对象
其中纯虚析构须要声明也需要实现(属于抽象类无法实例化对象)
class Animal { public: Animal() { cout << "A调用" << endl; } virtual void speak() = 0; //virtual ~Animal() //使用~Animal不会调用子类的虚析构,shiyongvirtual~aNIAML()可以解决该类问题 //{ // cout << "删除" << endl; //} //纯虚析构 virtual ~Animal()=0; }; Animal::~Animal() { cout << "纯虚删除" << endl; } class Cat:public Animal { public: Cat(string name)//析构 {m_name=new string(name);} virtual void speak() {cout <<*m_name<< "喵喵" << endl;} ~Cat()//虚析构 { if (m_name != NULL) { delete m_name; m_name = NULL;}} string* m_name;}; int main() { Animal* animal = new Cat("Tom"); animal->speak(); delete animal;//父类指针在析构时不会调用子类的析构,导致有数据泄露情况 return 0;}
标签:函数,子类,多态,纯虚,抽象类,父类,虚析构 来源: https://www.cnblogs.com/lyj00/p/15826573.html