在父类的构造函数或析构函数中调用虚函数,调用的不是子类的重载函数,而就是这个类的相应函数。但是如果在父类的其它函数中调用虚函数,会调用到子类的重载函数。

其实这个是很容易理解的,构造函数调用的顺序,是先调用父类的构造函数,再调用子类的构造函数。由于父类的构造函数运行的时候,子类甚至没被初始化,所以不好调用子类的虚函数。反过来看,析构函数是从子类开始调用到父类,父类的析构函数调用的时候,子类已经析构了,这时虚函数也不能够调用子类的。

看代码就知道了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
class A {
public:
    A() { func(); }
    virtual ~A() { func(); }
    void test() { func(); }
    virtual void func() { cout << "A"; }
};
class B : public A {
public:
    B() { func(); }
    virtual ~B() { func(); }
    virtual void func() { cout << "B"; }
};
int main() {
    B *pb = new B(); // Output: AB
    cout << endl;
    A *pa = (A *)pb;
    pa->test(); // Output: B
    pa = NULL;
    cout << endl;
    delete pb; // Output: BA
    cout << endl;
    return 0;
}

原创文章,转载请注明来源:http://euyuil.com/3017/cplusplus-invoke-virtual-in-constructors-destructors/