- 构造函数中的虚函数
不要再构造函数内调用虚函数,此时派生类对象还未被构造出来,因此调用的是基类的虚函数。
#include<iostream>
using namespace std;
class MClass1{
public:
MClass1(){func();};
~MClass1(){};
virtual void func(){
cout<<"MClass1\n";
};
};
class MClass2:public MClass1{
public:
MClass2(){func();};
~MClass2(){};
void func()override{
cout<<"MClass2\n";
};
};
int main(){
MClass1* m = new MClass2();
}
运行结果如下图所示:
- 析构函数中的虚函数
派生类对象在基类析构函数执行前已被销毁,因此调用的是基类的虚函数。
#include<iostream>
using namespace std;
class MClass1{
public:
MClass1(){};
~MClass1(){func();};
virtual void func(){
cout<<"MClass1\n";
};
};
class MClass2:public MClass1{
public:
MClass2(){};
~MClass2(){func();};
void func()override{
cout<<"MClass2\n";
};
};
int main(){
MClass1* m = new MClass2();
delete m;
}
运行结果如下图所示:
- 虚函数中的默认形参由静态类型决定
即使实际运行的是派生类中的函数,传入函数的也是基类函数定义地默认实参。
#include<iostream>
using namespace std;
class MClass1{
public:
MClass1(){};
~MClass1(){};
virtual void func(int a=10){
cout<<"MClass1\n";
cout<<"a = "<<a<<endl;
};
};
class MClass2:public MClass1{
public:
MClass2(){};
~MClass2(){};
void func(int a=20)override{
cout<<"MClass2\n";
cout<<"a = "<<a<<endl;
};
};
int main(){
MClass1* m = new MClass2();
m->func();
delete m;
}
运行结果如下:
- 结论
- 不要在构造函数内调用virtual函数。
- 如果虚函数使用默认实参,则基类和派生类的默认实参最好一致。