什么类成员函数不能成为虚函数
- 构造函数,虚函数是运行时多态,必须根据对象类型动态绑定。而调用构造函数时还不存在对象。
- static成员函数,属于一个类,而不特属于某个对象,因此不能是虚函数。
- 内联函数,内联在编译时展开,而虚函数是运行时动态绑定。
什么类成员函数必须成为虚函数
- 当一个类作为基类时,其析构函数必须是虚函数,否则可能没办法正确析构其派生类
看以下几段代码:
#include<iostream>
using namespace std;
class Base{
public:
Base() {};
~Base() {cout << "Output from the destructor of class Base!" << endl;};
void DoSomething() { cout << "Do something in class Base!" << endl; };
};
class Derived : public Base{
public:
Derived() {};
~Derived() { cout << "Output from the destructor of class Derived!" << endl; };
void DoSomething() { cout << "Do something in class Derived!" << endl; };
};
int main(){
Derived *p = new Derived;
p->DoSomething();
delete p;
return 0;
}
在上述代码中,我们new了一个派生对象,析构时会先调用派生类析构函数,再调用基类析构函数,不存在内存泄漏问题。
输出如下
:
再看一段代码,与上一段代码仅在main函数段有区别:
#include<iostream>
using namespace std;
class Base {
public:
Base() {};
~Base() { cout << "Output from the destructor of class Base!" << endl; };
void DoSomething() { cout << "Do something in class Base!" << endl; };
};
class Derived : public Base {
public:
Derived() {};
~Derived() { cout << "Output from the destructor of class Derived!" << endl; };
void DoSomething() { cout << "Do something in class Derived!" << endl; };
};
int main() {
Base *p = new Derived;
p->DoSomething();
delete p;
return 0;
}
上述代码是一种常见的动态绑定方法——基类指针指向派生类对象。
输出如下
,可见其没有调用派生类析构函数,可能发生内存泄漏:
在基类析构前加上virtual,再看看输出结果:
这就是在类作为基类时,其析构函数需要成为虚函数的原因。换言之,若不作为基类,则没有必要加virtual,否则会带来对象数 * 指针大小的额外空间开销