1,析构函数什么时候需要为virtual型。我们先来看一个程序:
#include<iostream>
using namespace std;
class A
{
public:
A(){ cout << "construct BASE"<<endl;}
~A() {cout << "Destruct BASE"<<endl;}
};
class B:public A
{
public:
B(){cout << "construct DERIVE"<<endl;}
~B(){cout<<"Destruct DERIVE"<<endl;}
};
void main()
{
A *point = new B;
delete point;
}
我们先看一下输出
A *point = new B;我们开辟了一个子类空间赋给了基类,再删除它,本来应该调用子类析构函数释放空间,但是从运行来看调用的是基类析构函数,所以如果你在子类析构函数中如果进行了内存释放,那么很可惜他根本没有释放,真是事与愿违。那么如果我们将基类中的析构函数定义为 virtual 型呢??
可以看到子类的析构函数也得到了调用,这个正和我们的心意。
所以如果你像程序中一样,用基类的指针指向了子类的空间,而且在子类的析构函数中你有释放内存空间,那么必须将基类的析构函数定义为virtual否则无法释放内存空间。当然也不是所有的析构函数都要为virtual型如果上面的两个条件有一个不满足,那就没有必要毕竟虚函数需要浪费一定的内存空间。
我没再来讨论一下多态;
假设我们的基类只是对外提供了一些接口。
#include<iostream>
using namespace std;
class A
{
public:
A(){ cout << "construct BASE"<<endl;}
virtual ~A() {cout << "Destruct BASE"<<endl;}
virtual do1() = 0; //纯虚函数
};
class B:public A
{
public:
B(){cout << "construct DERIVE"<<endl;}
~B(){cout<<"Destruct DERIVE"<<endl;}
virtual do1(){cout <<"do1 something in DERIVE"<<endl;}
void do2(){cout<<"aaaaaaaa"<<endl;}
};
void main()
{
A *point = new B;
point ->do1(); //访问子类的do1;
point ->do2(); // 错误提示指明do2不是基类的成员
delete point;
}
两种方式:1. B *point1 = (B *)(point);
point1 ->do2();
2, B *point1 = dynamic_cast<B *>(point);
point1 ->do2();
这就相当于类型的强制转换。不过第一种方法不安全,建议使用第二种,使用前先保证你的vc设置好了。
project -> setting->C/C++->category中选C++language 将下面Enable Run-time type information(RTTI)前的勾选上。