__declspec(novtable)作用

__declspec(novtable) 在C++中接口中广泛应用. 不容易看到它是因为在很多地方它都被定义成为了宏. 比如说ATL活动模板库中的ATL_NO_VTABLE, 其实就是__declspec(novtable).
__declspec(novtable) 就是让类不要有虚函数表以及对虚函数表的初始化代码, 这样可以节省运行时间和空间. 但是这个类一定不允许生成实例, 因为没有虚函数表, 就无法对虚函数进行调用. 因此, __declspec(novtable)一般是应用于接口(其实就是包含纯虚函数的类), 因为接口包含的都是纯虚函数, 不可能生成实例. 我们把 __declspec(novtable)应用到接口类中, 这些接口类就不用包含虚函数表和初始化虚函数表的代码了. 它的派生类会自己包含自己的虚函数表和初始化代码.

此外还有 AFX_NOVTABLE
AFX_NOVTABLE 是什么东东?是个宏,在Afxver_.h中:

#if _MSC_VER >= 1100 && !defined(_DEBUG)
#define AFX_NOVTABLE __declspec(novtable)
#else
#define AFX_NOVTABLE
#endif

也就是说在你编译Release版本时,在CObject前是__declspec(novtable),在debug版本没有这个限制。MSDN里的解释是:

-----------------------------------------------------------------

Microsoft Specific
This is a __declspec extended attribute. 
This form of __declspec can be applied to any class declaration, but should only be applied to pure interface classes, that is, classes that will never be instantiated on their own. The __declspec stops the compiler from generating code to initialize the vfptr in the constructor(s) and destructor of the class. In many cases, this removes the only references to the vtable that are associated with the class and, thus, the linker will remove it. Using this form of __declspec can result in a significant reduction in code size.
If you attempt to instantiate a class marked with novtable and then access a class member, you will receive an access violation (AV).
Example
// novtable.cpp
#include <stdio.h>
class __declspec(novtable) X
{
public:
   virtual void mf();
};
class Y : public X
{
public:
   void mf()
   {
      printf("In Y\n");
   }
};
int main()
{
   // X *pX = new X();
   // pX->mf();   // AV at runtime
   Y *pY = new Y();
   pY->mf();
}Output
In YEND Microsoft Specific
-----------------------------------------------------------------

依照AFX_NOVTABLE的声明,对CObject在debug模式,是不起作用的,而在release模式时将移除CObject的vtable,这是release比debug版本的尺寸小的原因之一吧。

赞(0) 打赏
取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

    暂无评论...