Effective C++: 不要在构造函数和析构函数中调用任何虚函数
对于包含虚函数的C++对象,都会有一个虚表指针vptr指向一个虚函数列表,这个虚表是属于这个类的,也就是所有这个类对象持有同一个虚表指针。那么这个这个指针时何时被赋予的,用VS调试了下,过程如下:
假设class Student: public Person
Person* p = new Student;
在Student的构造中,
1.首先会进入Person的构造函数,这个时候vptr指针指向的是Person类的虚表。这就是在父类构造函数中调用虚函数不生效的原因,因为这个时候vptr还是Person自己的。
2.构造Student类成员,这个时候vptr还是指向Person的虚表
3.进入Student构造函数。这个时候vptr已经是指向Student类的虚表了。
构造类成员对象->vptr赋值->调用该类构造函数。
从上面的情况看,在构造函数中调用虚函数是可以的,只是可能不会是想要的结果,因为虚函数指针还是当前类,不会有任何多态效果。
delete p;
那么在析构时会发生什么:
1.调用Student析构函数,这个时候发现vptr已经替换成指向Person的指针了
2.调用Student成员对象的析构函数
3.调用Person析构函数
所以也不要指望Person析构函数中的虚函数会起作用,因为在轮到他执行的时候指针已经指向Person的虚表了。
以上是在VS编译器中调试的结果,其他编译器中还不清楚。所以要求就是最开始调到的那句。