背景不多说了,直接看代码吧。
#include <iostream>
using namespace std;
class base_t {
public:
void process() {
print();
}
virtual void print() {
cout<<"base_t"<<endl;;
}
};
class inhert_t : public base_t {
public:
inhert_t() {
cout<<"con"<<endl;
}
virtual void print() {
cout<<"inhert_t"<<endl;
}
};
typedef struct {
inhert_t inhert;
}thread_data_t;
int main() {
thread_data_t* p_thread_data = (thread_data_t*)malloc(sizeof(thread_data_t));
p_thread_data->inhert.process(); //1
p_thread_data->inhert.print(); //2
inhert_t* p_inhert = &p_thread_data->inhert;
p_inhert->process(); //3
p_inhert->print(); //4
p_inhert = (inhert_t*)malloc(sizeof(inhert_t));
p_inhert->process(); //5
p_inhert->print(); //6
inhert_t& inhert = *(p_inhert);
inhert.process(); //7
inhert.print(); //8
}
上面的语句有可能发生异常。
事实上,[2]不会有异常,但是其它会出现异常。
例子中使用了malloc创建实例。
但是虚表指针是在构造函数中被初始化的;虚函数也是通过虚表指针来调用的。
由于虚表指针为0,导致了虚函数调用失败。
但是[2]之所以没有失败,通过查看汇编语句可以看出,这个虚函数调用没有使用虚表指针跳转,而是直接使用函数地址。其实也是很好理解的。