51.虚构函数和纯虚构函数
1.抽象基类和纯虚函数
在设计时,常常希望基类仅仅作为其派生类的一个接口。这就是说,仅想对基类进行向上类型转换,使用它的接口,而不希望用户实际的创建一个基类的对象。同时创建一个纯虚函数允许接口中放置成员原函数,而不一定要提供一段可能对这个函数毫无意义的代码。
做到这点,可以在基类中加入至少一个纯虚函数(pure virtual function),使得基类称为抽象类(abstract class).
■ 纯虚函数使用关键字virtual,并在其后面加上=0。如果试图去实例化一个抽象类,编译器则会阻止这种操作。
■当继承一个抽象类的时候,必须实现所有的纯虚函数,否则由抽象类派生的类也是一个抽象类。
■Virtual void fun() = 0;告诉编译器在vtable中为函数保留一个位置,但在这个特定位置不放地址。
2.视频内容
程序1:
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS 1
//2022年10月19日20:01:43
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{
cout << "Animal的构造" << endl;
}
~Animal()
{
cout << "Animal的构造" << endl;
}
};
class Son:public Animal
{
public:
Son()
{
cout << "Son的构造" << endl;
pName = new char[64];
memset(pName, 0, 64);
strcpy(pName, "如花");
}
~Son()
{
cout << "Son析构" << endl;
if( pName != NULL )
{
delete[] pName;
pName = NULL;
}
}
public:
char *pName;
};
void test()
{
Animal *animal = new Son;
delete animal;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
输出结果:
Animal的构造
Son的构造
Animal的构造
请按任意键继续. . .
程序2:
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS 1
//2022年10月19日20:01:43
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{
cout << "Animal的构造" << endl;
}
//虚析构函数会调用子类的析构函数
//virtual ~Animal()
//{
// cout << "Animal的析构" << endl;
//}
//纯虚析构函数,纯虚析构函数需要在类外实现
virtual ~Animal() = 0;
};
Animal::~Animal()
{
cout << "Animal的析构" << endl;
}
class Son:public Animal
{
public:
Son()
{
cout << "Son的构造" << endl;
pName = new char[64];
memset(pName, 0, 64);
strcpy(pName, "如花");
}
~Son()
{
cout << "Son析构" << endl;
if( pName != NULL )
{
delete[] pName;
pName = NULL;
}
}
public:
char *pName;
};
void test()
{
Animal *animal = new Son;
delete animal;//发生了静态联编
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
输出结果:
Animal的构造
Son的构造
Son析构
Animal的析构
请按任意键继续. . .
3.虚析构函数和纯虚析构函数(重点)
1.虚析构函数是为了解决基类指针指向派生类对象,并用基类指针释放派生类对象
2.纯虚析构函数,有纯虚析构函数的类是抽象类,不能实例化对象
注意:纯虚析构函数需要在类外实现
3.虚析构函数和纯虚析构函数的区别:
1.有纯虚析构函数的类是抽象类,不能实例化对象,而且要在类外实现
2.虚析构函数不需要在类外实现
参考资料
参考资料来源于黑马程序员等