C++基础复习提升-纯虚函数和抽象类那些事
参考C++那些事-光城大佬的网站
上一篇C++基础复习提升-sizeof那些事
下一篇C++基础复习提升-vptr和vtable那些事
1.1纯虚函数与抽象类
抽象类是包含纯虚函数的类,抽象类只能作为基类来派生新类使用,不能创建对象,但是可以创建指针。
//inline.h
#ifndef TEST
//抽象类
class A {
// 纯虚函数
virtual void method() = 0;
void test() {};
};
#endif
//main.cpp
#include <iostream>
#include "inline.h"
using namespace std;
int main() {
//抽象类 error:A a;无法创建对象,无法实例化
//error:A *ptr = new A();
//可以创建抽象类的指针
A *ptr;
return 0;
}
1.2实现抽象类
抽象类中:在成员函数内可以调用纯虚函数,在构造析构函数内部不能调用纯虚函数,如果一个类继承了抽象类,那么它必须实现了基类中的所有纯虚函数,才能成为非抽象类。
//inline.h
#ifndef TEST
//抽象类
class A {
public:
// 纯虚函数
virtual void pure_method() = 0;
// 抽象类中成员函数内调用this指针访问纯虚函数
void test();
// 构造和析构函数无法调用纯虚函数
// A()=default;创建默认的构造函数和析构函数
A() = default;
~A() = default;
};
//只有实现了抽象类全部的纯虚函数的派生类,才是非抽象类
class B : public A {
public:
void pure_method() override;
};
#endif
//main.cpp
#include <iostream>
#include "inline.h"
using namespace std;
void A::test() { this->pure_method(); }
void B::pure_method() { cout << "B.pure_method" << endl; }
int main() {
B b;
// 调用了派生类中实现的纯虚函数
// 输出:B.pure_method
b.test();
// 使用多态,抽象类的指针和引用指向抽象类派生出的类的对象
A *ptr = new B();
ptr->pure_method();
return 0;
}
1.3抽象类实现多态时虚析构与非虚析构的调用
当基类指针指向派生类对象并删除对象时,我们希望调用的析构函数顺序是先调用派生类再调用基类析构,但是若基类的析构函数是非虚析构时,则只能调用基类的析构函数
//inline.h
#ifndef TEST
//抽象类
class A {
public:
// 纯虚函数
virtual void pure_method() = 0;
// 抽象类中成员函数内调用this指针访问纯虚函数
void test();
// 构造和析构函数无法调用纯虚函数
// A()=default;创建默认的构造函数和析构函数
A() = default;
// 虚析构
virtual ~A();
};
//只有实现了抽象类全部的纯虚函数的派生类,才是非抽象类
class B : public A {
public:
void pure_method() override;
~B() override;
};
#endif
//main.cpp
#include <iostream>
#include "inline.h"
using namespace std;
void A::test() { this->pure_method(); }
void B::pure_method() { cout << "B.pure_method" << endl; }
A::~A() { cout << "destructure func: A" << endl; }
B::~B() { cout << "destructure func: B" << endl; }
int main() {
// 使用多态,抽象类的指针和引用指向抽象类派生出的类的对象
A *ptr = new B();
// 若抽象类中的析构函数是非虚函数,那么销毁ptr时,只会调用基类A的析构函数
// 输出:destructure func: B \n destructure func: A
delete ptr;
return 0;
}