__ declspec(novtable)`没用吗?

问题描述 投票:0回答:2

我们知道,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编译

c++ visual-c++ virtual
2个回答
1
投票

[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中查找以找到BDerivedBDerived的实现。 >


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

fun

2
投票

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); 读取:

© www.soinside.com 2019 - 2024. All rights reserved.