纯虚函数
纯虚函数是一种特殊的虚函数,在某些情况下,基类中不能对虚函数给出有意义的实现,把它声明为纯虚函数。
纯虚函数只有函数名、参数和返回值类型,没有函数体,具体实现留给该派生类去做。
语法:virtual 返回值类型函数名 (参数列表)=0;
纯虚函数在基类中为派生类保留一个函数的名字,以便派生类它进行重定义。如果在基类中没有保留函数名字,则无法支持多态性。
含有纯虚函数的类被称为抽象基类,不能实例化对象,可以创建指针和引用。
派生类必须重定义抽象类中的纯虚函数,否则也属于抽象类。
派生类必须重定义抽象类中的纯虚函数,否则也属于抽象类。
基类中的纯虚析构函数也需要实现。
思考:
有时候,想使一个类成为抽象类,但刚好又没有任何纯虚函数,怎么办?
方法很简单:在想要成为抽象类的类中声明一个纯虚析构函数。
运行阶段类型识别dynamic_cast
多态的精髓就是基类指针可以指向派生类对象,试想一下,我们在运行的时候怎么知道当前基类指针指向的是哪个派生类对象,例如,在之前举过的例子中,我们想让当创建A时,他说一句话时我是A,怎么实现呢?一种是我们判断当num=1时,调用派生类的函数,但是加入我们不知道num呢?下面演示
#include<iostream>
using namespace std;
class Person
{
public:
int m_a = 1;
virtual void hello() { cout << "hello" << endl; }
virtual void wave() { cout << "向你挥手" << endl; }
};
class A:public Person
{
public:
void hello() { cout << "A:hello" << endl; }
void wave() { cout << "A:向你挥手" << endl; }
void speak() { cout << "我是A" << endl; }
};
class B :public Person
{
public:
void hello() { cout << "B:hello" << endl; }
void wave() { cout << "B:向你挥手" << endl; }
};
int main()
{
//不使用 1->A,2->B
int num;
cin >> num;
Person* ptr = nullptr;
//if (num == 1)
//{
// A* pa = (A*)ptr; // C风格强制转换的方法,程序员必须保证目标类型正确。
// pa->speak();
//}
A* pa = dynamic_cast<A*>(ptr);
if (pa != nullptr)
pa->speak();
if (num == 1)
{
ptr = new A;
}
else if(num==2)
{
ptr = new B;
}
ptr->hello();
ptr->wave();
return 0;
}
dynamic_cast运算符用指向基类的指针来生成派生类的指针,它不能回答“指针指向的是什么类的对象”的问题,但能回答“是否可以安全的将对象的地址赋给特定类的指针”的问题。
语法:派生类指针 = dynamic_cast<派生类类型 *>(基类指针);
如果转换成功,dynamic_cast返回对象的地址,如果失败,返回nullptr。
注意:
1)dynamic_cast只适用于包含虚函数的类。
2)dynamic_cast可以将派生类指针转换为基类指针,这种画蛇添足的做法没有意义。
3)dynamic_cast可以用于引用,但是,没有与空指针对应的引用值,如果转换请求不正确,会出现bad_cast异常。