这个c++宏在做什么
What is this c++ macro doing?
我不明白下面的宏在做什么?如果有人能帮我看,我将不胜感激。
#define BASE_OFFSET(ClassName,BaseName)
(DWORD(static_cast < BaseName* >( reinterpret_cast
< ClassName* >(Ox10000000)))-Ox10000000)
如果有人想知道它是从哪里来的,它来自Don-Box Book Essential COM的第三章,他正在使用接口表构建QueryInterface函数,上面的宏以某种方式被用来找到指向类的接口vtable的指针,其中class是实现BaseName的ClassName,尽管我不知道它是如何做到的。
它告诉编译器:"假设在0x10000000处有一个ClassName
对象。相对于0x10000000",BaseName
数据将从该对象的何处开始?
想象一个具有多个基的类对象的内存布局:
class A: B, C{};
在构成A对象的内存块中,有属于B的数据块,也有属于C的数据块和特定于A的数据。由于至少一个基数据的地址不能与整个类实例的地址相同,因此传递给不同方法的this
指针的数值需要有所不同。宏检索差值。
EDIT:按照惯例,指向vtable的指针是任何具有虚拟函数的类中的第一个数据成员。因此,通过找到基础数据的地址,就可以找到其vtable指针的地址。
现在,关于类型转换。通常,当您键入指针时,操作在内部是琐碎的——地址的数值不取决于它指向的类型;数据类型的概念只存在于C级。不过,有一个重要的例外——当您使用多个继承来强制转换对象指针时。正如我们刚刚讨论的那样,需要传递给基类方法的this
指针可能在数值上与派生对象的指针不同。
因此,static_cast和interpret_cast之间的区别巧妙地捕捉到了这种差异。当你使用reinterpret_cast时,你告诉编译器:"我更清楚。取这个数值,并将其解释为指向我所说内容的指针"。这是一种蓄意颠覆类型体系的行为,危险,但偶尔也有必要。根据定义,这种类型的转换是琐碎的——因为你这么说
我所说的"琐碎"是指指针的数值不会改变。
static_cast是一个更高级的构造。在这种特殊的情况下,您将在对象及其基础之间进行投射。在C++类规则下,这是一个合理、安全的类型转换,但在数值上可能是不平凡的。这就是宏使用两种不同类型转换的原因。static_cast不违反类型系统。
概括一下:
reinterpret_cast<ClassName* >(OxlOOOOOOO)
是不安全的操作。它返回一个指向伪对象的伪指针,但这没关系,因为我们从不取消引用它
static_cast<BaseName*>(...)
是一个安全的操作(具有讽刺意味的是,使用了一个不安全的指针)。这是发生非平凡指针类型转换的部分。
(DWORD(...)-OxlOOOOOOO)
是纯粹的算术。这就是不安全加倍的地方:我们不把指针用作指针,而是把它投射回一个整数,忘记了它曾经是一个指针。
最后一个阶段可以等效地改写为:
((char*)(...)-(char*)OxlOOOOOOO)
如果这更有意义的话。
关于魔术0x10000000常数的备注。
如果该常量为0,GCC将显示警告-Winvalid偏移量为(当然,如果启用了它)。也许其他编译器也会这样做。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 我应该使用什么来代替void作为变体中的替代类型之一
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用