__declspec(novtable)有什么作用

__declspec(novtable) 在C++中接口中广泛应用. 不容易看到它是因为在很多地方它都被定义成为了宏. 比如说ATL活动模板库中的ATL_NO_VTABLE, 其实就是__declspec(novtable).

 __declspec(novtable) 就是让类不要有虚函数表以及对虚函数表的初始化代码, 这样可以节省运行时间和空间. 但是这个类一定不允许生成实例, 因为没有虚函数表, 就无法对虚函数进行调用. 因此, __declspec(novtable)一般是应用于接口(其实就是包含纯虚函数的类), 因为接口包含的都是纯虚函数, 不可能生成实例. 我们把 __declspec(novtable)应用到接口类中, 这些接口类就不用包含虚函数表和初始化虚函数表的代码了. 它的派生类会自己包含自己的虚函数表和初始化代码. 

如下代码使用__declspec(novtable)

struct __declspec( dllexport ) A
{
	virtual void func()=0;
};
struct __declspec( dllexport ) __declspec(novtable) B : public A
{
	
};

struct __declspec( dllexport ) C : public B
{
	virtual void func()
	{
	}
};
用dependency walker查看如下

A::A(void)
A::A(struct A const &)
struct A & A::operator=(struct A const &)
B::B(void)
B::B(struct B const &)
struct B & B::operator=(struct B const &)
void C::func(void)
C::C(void)
C::C(struct C const &)
struct C & C::operator=(struct C const &)
const A::`vftable'
const C::`vftable'
如果代码未使用 __declspec(novtable),则

A::A(void)
A::A(struct A const &)
struct A & A::operator=(struct A const &)
B::B(void)
B::B(struct B const &)
struct B & B::operator=(struct B const &)
void C::func(void)
C::C(void)
C::C(struct C const &)
struct C & C::operator=(struct C const &)
const A::`vftable'
const B::`vftable'    //<=====区别在这里
const C::`vftable'

V TA B L E(虚函数表)和VPTR(指向虚函数标的指针)的区别

编译器到底做了什么实现的虚函数的晚绑定呢?我们来探个究竟。
 编译器对每个包含虚函数的类创建一个表(称为V TA B L E)。在V TA B L E中,编译器放置特定类的虚函数地址。在每个带有虚函数的类中,编译器秘密地置一指针,称为v p o i n t e r(缩写为V P T R),指向这个对象的V TA B L E。通过基类指针做虚函数调用时(也就是做多态调用时),编译器静态地插入取得这个V P T R,并在V TA B L E表中查找函数地址的代码,这样就能调用正确的函数使晚捆绑发生。为每个类设置V TA B L E、初始化V P T R、为虚函数调用插入代码,所有这些都是自动发生的,所以我们不必担心这些。利用虚函数,这个对象的合适的函数就能被调用,哪怕在编译器还不知道这个对象的特定类型的情况下。(《 C++编程思想 》)




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值