简介
- 在C++中,纯虚函数是一个在基类中声明但没有实现的虚函数。纯虚函数的声明以 “= 0” 结尾。纯虚函数的目的是为了提供一个接口,但是不提供实现。派生类必须实现纯虚函数,否则它也会成为一个抽象类。纯虚函数可以在基类中定义,也可以在派生类中定义。
- 纯虚函数用于创建抽象类,抽象类不能直接创建对象,只能作为基类来为派生类提供接口。派生类必须实现纯虚函数,否则派生类也会成为抽象类。
引入原因
- 为了实现C++的多态
抽象类
- 包含纯虚函数的类称为抽象类。
- 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。
抽象类的作用
- 抽象类的主要作用作为接口,由它来为派生类提供一个公共的根,在派生类中具体实现。
- 所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。
使用抽象类时注意:
- 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。
- 如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。
- 如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。
示例代码如下:
#include <iostream>
using namespace std;class Shape {protected:int width, height;public:virtual int area() = 0; // 纯虚函数void setWidth(int w) {width = w;}void setHeight(int h) {height = h;}
};class Rectangle: public Shape {public:int area() {return width * height;}
};class Triangle: public Shape {public:int area() {return (width * height) / 2;}
};int main() {Rectangle rect;Triangle tri;rect.setWidth(5);rect.setHeight(7);cout << "矩形的面积:" << rect.area() << endl;tri.setWidth(5);tri.setHeight(7);cout << "三角形的面积:" << tri.area() << endl;return 0;
}
在上面的示例中,Shape是一个抽象类,它有一个纯虚函数area()。Rectangle和Triangle是Shape的派生类,它们必须实现纯虚函数area()。在main函数中,我们创建了Rectangle和Triangle的对象,并调用它们的area()函数来计算面积。
Qt_纯虚函数的信号和槽
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);Obj = new BClass();QObject::connect(Obj, &AClass::signalPureVirtualFunction, [&](){std::cout << "in 1" << std::endl;});
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{Obj->pureVirtualFunction();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <iostream>
QT_BEGIN_NAMESPACE
namespace Ui
{class MainWindow;
}
QT_END_NAMESPACEclass AClass : public QObject
{Q_OBJECT
public:virtual void pureVirtualFunction() = 0;signals:void signalPureVirtualFunction();
};class BClass : public AClass
{Q_OBJECT
public:void pureVirtualFunction() override{std::cout << "send" << std::endl;emit signalPureVirtualFunction();}
};class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_clicked();private:Ui::MainWindow *ui;AClass *Obj;
};
#endif // MAINWINDOW_H