__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++编程思想 》)

__declspec(novtable)有什么作用相关推荐

  1. __declspec(novtable) 的用法

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

  2. c++ 中__declspec 的用法

    语法说明: __declspec ( extended-decl-modifier-seq ) 扩展修饰符: 1:align(#)     用__declspec(align(#))精确控制用户自定数 ...

  3. __declspec关键字详细用法

    __declspec关键字详细用法 2009-01-21 16:23 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与ext ...

  4. __declspec

    __declspec __cdecl和__stdcall都是函数调用规范(还有一个__fastcall),规定了参数出入栈的顺序和方法, 如果只用VC编程的话可以不用关心,但是要在C++和Pascal ...

  5. 【转】__declspec用法详解

    __declspec用法详解 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与extern等是C和 C++语言的ANSI规范 ...

  6. C++ 性能剖析 (四):Inheritance 对性能的影响

    (这个editor今天有毛病,把我的format全搞乱了,抱歉!) Inheritance 是OOP 的一个重要特征.虽然业界有许多同行不喜欢inheritance,但是正确地使用inheritanc ...

  7. 浅析 C++智能指针和 enable_shared_from_this 机制

    作者 | 小牛  责编 | 阿哲 头图 | CSDN 下载自视觉中国 来源 | 后端技术小牛说(ID:gh_acfd77ed3228) 今天跟聊一下 BAT 面试 C++ 开发工程师必问的一个考点:智 ...

  8. 从源码看std::weak_ptr

    1. 序 本篇文章来讲解一下weak_ptr, weak_ptr一般也都是和shared_ptr同时存在的,相当于对对象的弱化版引用.我们首先从源码的角度来讲解下weak_ptr,然后再讲一下weak ...

  9. __purecall 链接错误

    不知道诸位有没有过这样的经历:本是简单合法的 C++ 代码,但编译链接的时候却出现了如下的链接错误: > error LNK2001: 无法解析的外部符号 __purecall 在解决这个问题之 ...

最新文章

  1. JavaScript之substring()方法讲解
  2. NCP1271的使用
  3. 伪官宣:Envoy 中文指南新鲜出炉
  4. leetcode_add_two_numbers
  5. 仿ArrayList功能的bag类
  6. react 版权问题_react使用fetch封装请求的方法-简单易懂
  7. C语言辅导试题答案,C语言试题含答案).doc
  8. 基于WDF的PCI/PCIe接口卡Windows驱动程序(3)- 驱动程序代码(头文件)
  9. 从安全和不安全两个角度,教你如何发布对象(含各种单例代码)
  10. Happy Programming Contest
  11. gnuplot在windows下的安装和使用
  12. lamda表达式修改数据_关系数据库SQL语言简介
  13. SSM通信研究:如何拦截SSM代理流量
  14. 算法设计与分析 第一章 基础知识作业1
  15. MSC.MD.NASTRAN.V2010\
  16. 植物研究最新进展(2021年11月)
  17. Maya 2023安装步骤(附安装、汉化、图文教程)
  18. 用 M1 MacBook 当主力开发机:程序员使用半个月后如是说
  19. MacBook Pro 触控板目前没有触感反馈怎么办?
  20. RS507-ASEMI整流桥RS507

热门文章

  1. linux核心的最新版本,求问Linux最新内核版本以及发布日期。
  2. Arm发布v9体系架构:Cortex-X2、Cortex-A710和Cortex-A510
  3. C语言学习笔记---时间函数strftime()
  4. MATLAB:虹膜识别的图像灰度化处理,直方图均衡化
  5. C++程序代码:利用【函数】——画正三角形、倒三角形
  6. C++特殊符号:【优先级】
  7. (五)Qt实现自定义模型基于QAbstractItemModel
  8. Vue.js 条件与循环
  9. 如何在复杂的分布式系统中做测试
  10. 利用Adorner制作用于图像裁切的选择框