我们知道,novtable
表示不为纯抽象类创建虚拟表。但是,当我运行代码打击时,出了点问题:
#include <iostream>
using namespace std;
struct A{
virtual void fun() = 0;
};
struct __declspec(novtable) B{
virtual void fun() = 0;
};
struct C{
void fun(){}
};
struct _declspec(novtable) D : public A {};
int main(){
cout<<sizeof(int*)<<endl; //4
cout<<sizeof(A)<<endl; //4
cout<<sizeof(B)<<endl; //4
cout<<sizeof(C)<<endl; //1
cout<<sizeof(D)<<endl; //4
return 0;
}
A
和B
的大小相同,是否意味着novtable
没有用?
ps:用vs2019编译
[v0类没有vtable。这并不意味着在B
实例的对象中没有vtable pointer。需要vtable指针,以便
例如,如果您创建BDerived的实例:
B
struct BDerived : public B {
void fun() {}
};
BDerived bd;
B* pb = &bd;
pb->fun();
指向pb
子对象,该子对象包含一个vtable指针,该指针指向B
的vtable。当您调用BDerived
时,程序将查看pb->fun()
的vtable指针,将其跟随到pb
的vtable,然后在该vtable中查找以找到BDerived
的BDerived
的实现。 >
换句话说,编译器将代码转换为如下代码:
fun
vtable A_vtable = {NULL};
struct A {
vtable *vtable_ptr;
};
// No vtable, but still a vtable pointer
struct B {
vtable *vtable_ptr;
};
void BDerived_fun() {};
vtable BDerived_vtable = {&BDerived_fun};
struct BDerived : public B {
};
BDerived bd; bd.vtable_ptr = &BDerived_vtable;
B* pb = &bd;
(pb->vtable_ptr.fun)(pb);
读取: