众所周知,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;
}


AB的大小相同,是否意味着novtable没有用?

ps:用vs2019编译

最佳答案

B没有vtable。这并不意味着B实例的对象中没有vtable指针。需要vtable指针,以便

例如,如果您创建BDerived的实例:

struct BDerived : public B {
    void fun() {}
};

BDerived bd;
B* pb = &bd;
pb->fun();


pb指向B子对象,该子对象包含一个vtable指针,该指针指向BDerived的vtable。调用pb->fun()时,程序将查看pb的vtable指针,将其跟随到BDerived的vtable,然后在该vtable中查找以找到BDerivedfun实现。



换句话说,编译器将代码转换为如下形式:

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);

关于c++ - __declspec(novtable)是否没有用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58931606/

10-13 06:48