纯虚函数的实例化问题

什么是纯虚函数
1、虚函数:
在基类中将一个函数声明为虚函数,使该函数具有虚属性,那么其所有派生函数中该函数的重写都具备了虚属性,也就使得基类指针可以调用派生类实例中继承自该基类的所有成员函数,且若有重写,调用的都是重写后的函数。
写法:

virtual 函数类型 函数名(参数列表); //虚函数

2、纯虚函数:
纯虚函数是一种特殊的虚函数,具有纯虚函数的类称为抽象类;
写法:

virtual 函数类型 函数名(参数列表) = 0; //纯虚函数

特点:
1、纯虚函数对类最大的束缚就是:类中一旦出现纯虚函数,就不可实例化了;

2、纯虚函数还是可以有函数体,只不过最终还是要被派生类重写,在派生类的函数中可以调用基类中有函数体的纯虚函数;

3、为使派生类能完全释放资源,基类析构函数必须声明为虚函数,否则,在用基类指针new一个派生类对象后,delete该指针就只能回收与基类相关的资源,造成内存泄漏;

4、纯虚析构函数必须要有函数体,根据C++析构函数的调用规则,派生类会调用基类析构函数,如果基类析构函数没有函数体会造成函数调用失败而报错,这是纯虚析构函数与普通纯虚函数不同之处。

作用:
在基类中无法对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去实现。相当于上层基类声明好接口,下层子类根据特性对接口进行实现。

例子1:

#include <iostream>


class VirtualClass {
    
    
public:
	virtual void fun1() = 0;//纯虚函数
	virtual void fun2() {
    
     };
	virtual ~VirtualClass();
	
};

class ClassA : public VirtualClass {
    
    
public:
	void fun1() {
    
    
		printf("The is ClassA fun1\n");
	};
	void fun2() {
    
    
		printf("The is ClassA fun2\n");
	};
	virtual ~ClassA();

};



VirtualClass:: ~VirtualClass() {
    
    
}

ClassA:: ~ClassA() {
    
    
}
VirtualClass* reVirtua();
int main() {
    
    

	//VirtualClass * virtualclass = new VirtualClass();//纯虚函数不能自己实例化(显式实例化)

	VirtualClass * virtualClass = new ClassA(); //实例化的是VirtualClass的派生类ClassA();
	ClassA * classA = new ClassA();
	classA->fun1();
	classA->fun2();
	virtualClass->fun1();
	virtualClass->fun2();
	VirtualClass* vi =reVirtua();

	vi->fun1();
	vi->fun2();

	return 0;

}


VirtualClass* reVirtua()
{
    
    
	VirtualClass *vi = new ClassA();

	return vi;

}


在这里插入图片描述
结果:
在这里插入图片描述

例子2:
在学习CLAHE算法的时候发现OpenCV中算法的返回值是CLAHE类型的指针;

CV_EXPORTS_W Ptr<CLAHE> createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8));

需要CLAHE类型指针作为返回值:

	cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();

下面我们看一下CLAHE的类声明:

class CV_EXPORTS_W CLAHE : public Algorithm
{
    
    
public:
    /** @使用限制对比度的适应直方图均衡化来均衡灰度图像的直方图.
    @InputArray src 源图像,类型为 CV_8UC1 or CV_16UC1.
    @OutputArray  dst : 目标图像.
     */
    CV_WRAP virtual void apply(InputArray src, OutputArray dst) = 0;
//   注意这是纯虚函数:
// 	①纯虚函数没有函数体;
// 	②最后面的“ = 0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;
// 	③这是一个声明语句,最后应有分号。
  
 /** @设置对比度限制的阈值
    @double clipLimit: 阈值.
    */
    CV_WRAP virtual void setClipLimit(double clipLimit) = 0;

    //!返回阈值.
    CV_WRAP virtual double getClipLimit() const = 0;

    /** @设置直方图均衡化的网格大小。输入图像将被分割成大小相等的矩形瓦片.

    @Size tileGridSize  定义行和列中的块的数量
    */
    CV_WRAP virtual void setTilesGridSize(Size tileGridSize) = 0;

    //!@返回网格大小.
    CV_WRAP virtual Size getTilesGridSize() const = 0;
//!@垃圾回收.
    CV_WRAP virtual void collectGarbage() = 0;
};

里面都是纯虚函数,但是含有纯虚函数的类是抽象类,不能被实例化,
在这里插入图片描述
查看文档发现CLAHE在cuda中被继承了
在这里插入图片描述
在这里插入图片描述
所以我们可以推断,函数creatCLAHE的返回值为cv::CLAHE类型指向cv::cuda::CLAHE类型的指针;

猜你喜欢

转载自blog.csdn.net/qq_40595787/article/details/121012297