[英]Doing pointer math in a c++ class: Is it “legit”?
阿海,海,
我想知道是否可以执行以下操作:
class SomeClass
{
int bar;
};
SomeClass* foo = new SomeClass();
int offset = &(foo->bar) - foo;
SomeClass* another = new SomeClass();
*(another+offset) = 3; // try to set bar to 3
只是好奇Dan O
我想从技术上讲它可能会解决。
但是,有几个问题。 酒吧是私人的。 您正在混合使用不同类型的指针(指针算术依赖于指针类型:int * + 1和char * + 1的结果不同,因为int和char的大小不同)。
您是否也考虑过指向成员的指针:
#include <cassert>
struct SomeClass
{
int bar;
};
int main() {
int SomeClass::*mem_ptr = &SomeClass::bar;
SomeClass foo;
foo.*mem_ptr = 3;
assert(foo.bar == 3);
}
POD类的想法是好的(其他人对您的示例代码中的错误说了同样的话)。 对于非POD类,您不必仅通过与对象指针的偏移量来标识成员。 例如,考虑成员是否是基类的一部分,或者等效地,如果您想将偏移量应用于派生类的指针,但是涉及多重继承或虚拟继承。
但是,您知道成员指针吗?
struct SomeClass
{
int bar;
};
// fieldtoset is a pointer-to-member
int SomeClass::*fieldtoset = &SomeClass::bar;
SomeClass* another = new SomeClass();
// syntax works as if "*fieldtoset" is "bar" (the member variable referand)
another->*fieldtoset = 3 // set bar to 3
它没有任何问题,但是如果您不小心,将非常危险。
另一方面,您的代码是错误的。 (another + offset)的指针类型是什么? 它实际上是指向SomeClass的指针,而不是int,因此您至少应将指针转换为(int *):
*((int *)(another + offset)) = 3;
偏移量是另一个需要注意的问题,因为偏移量始终以指针指向的类型为单位。 简而言之,当int为4个字节长时,在(int *)
指针上加1实际上会对其加4,因此最好在进行计算之前将任何指针转换为(char *)。
因此,对于您的示例:
SomeClass* foo = new SomeClass();
int offset = (char *)&(foo->bar) - (char *)foo;
SomeClass* another = new SomeClass();
*((int *)((char *)another+offset)) = 3; // try to set bar to 3
您在示例中所做的并不是很好地使用指针。 如果编译器做的事情与您预期的不同,它可能无法正常工作,并且可以使用常规方法以简单,高效,较少的源代码完成它。
如果您有有效的使用,指针算术就没有错。 但是,该语言还没有覆盖很多。
没关系(通常您会为它定义一个宏,例如Windows DDK的CONTAINING_RECORD宏),但是我想问为什么在C ++中需要它? 通常,您在C中使用这些技巧。
查看原始地址,这似乎可行,但对于语句中的int offset = &(foo->bar) - foo;
者来说: int offset = &(foo->bar) - foo;
您正在尝试减去不同的指针类型。 因此,如果将reniterpret_cast转换为char *,它将为您提供所需的内容。
尽管这看起来太费解并且容易出错,但没有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.