2009-09-07 71 views
1

阿海,海,在C++类中做指针数学:它是“合法”吗?

我不知道它是否可以做一些类似如下:

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 

只是好奇, 丹奥

+0

请修复代码,以便在您访问它的位置访问“bar”。我们目前不知道你是否想要将它变成一个结构体或公共或某物。我认为回答你的问题很重要。 – 2009-09-07 18:28:58

+0

我的懒惰指针语法可能是一个更大的问题,私人/公众位......耸耸肩......将在下班后尝试编辑。 – 2009-09-07 21:39:56

+1

不,私人/公共事物也非常重要。它有助于确定班级是否为POD,这会以重要的方式影响答案。 – jalf 2009-09-08 00:43:42

回答

11

我想tecnically它可能会解决。

但是,有几个问题。酒吧是私人的。您正在混合不同类型的指针(指针算术依赖于指针类型: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); 
} 
+0

+1击败了我。 – 2009-09-07 18:12:53

+2

+1指向成员的指令似乎是原始提问者正在寻找的内容。 – GBegen 2009-09-07 18:29:17

+0

指向成员的指针非常有趣,我认为它不会允许我实现我正在考虑的设计(但这不是重点,这是对我提出的问题的一个很好的答案)。 – 2009-09-07 21:38:50

0

没关系(通常你会为它定义一个宏,像Windows DDK的CONTAINING_RECORD宏),但我会问为什么你需要这个在C++中;通常你在C中使用这些类型的技巧。

1

它没有什么问题,但如果你不小心,这是非常危险的。

另一方面,你的代码是错误的。 (另一个偏移量)的指针类型是什么?它实际上是一个指向SomeClass的,而不是一个int,所以你应该把指针至少投,与(int *):

*((int *)(another + offset)) = 3; 

偏移量是另一件事看出来,因为它总是在单位类型指针指向。简而言之,当int是4个字节长时,将1加到(int *)指针实际上会将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 
0

综观原地址,这似乎是它的工作,但在声明中首发:int offset = &(foo->bar) - foo;您正在尝试不同。减去指针类型。所以,如果你reniterpret_cast他们char *它应该给你你正在寻找什么。

虽然这看起来过于复杂,并且容易出错是有用的。

4

的想法是POD类OK(同样的事情其他人说,大约在您的示例代码中的错误)。对于非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 
+0

+1指向成员的指令似乎是原始提问者正在寻找的内容。 – GBegen 2009-09-07 18:29:50

+0

指向成员的东西很有趣,但可能不会用于我想要做的事情,最终我认为我将使用单个对象将我的值写入并复制完成。 – 2009-09-07 18:50:34

1

你在你的例子做什么不是一个好的使用指针。如果编译器执行的操作与您预期的不同,它可能无法正常工作,并且可以像使用普通方法一样简单,同样高效且使用较少源代码来完成。

如果您有有效的用法,指针算术没有任何问题。虽然没有很多已经被这门语言覆盖了。