假设在我的代码中,我必须将一个void*
作为数据成员存储并在需要时将其类型转换回原始class
指针。为了测试它的可靠性,我写了一个测试程序(linux ubuntu 4.4.1 g++ -04 -Wall),看到这个行为我很震惊。
struct A
{
int i;
static int c;
A () : i(c++) { cout<<"A() : i("<<i<<")\n"; }
};
int A::c;
int main ()
{
void *p = new A[3]; // good behavior for A* p = new A[3];
cout<<"p->i = "<<((A*)p)->i<<endl;
((A*&)p)++;
cout<<"p->i = "<<((A*)p)->i<<endl;
((A*&)p)++;
cout<<"p->i = "<<((A*)p)->i<<endl;
}
这只是一个测试程序;实际上,对于我的情况,必须将任何指针存储为void*
,然后将其转换回实际指针(在 的帮助下template
)。所以我们不要担心那部分。上述代码的输出是,
p->i = 0
p->i = 0 // ?? why not 1
p->i = 1
但是,如果您将其更改void* p;
为A* p;
它会给出预期的行为。为什么 ?
另一个问题,我无法逃避,(A*&)
否则我无法使用operator ++
;但它也会发出警告,因为取消引用类型双关指针会破坏严格的别名规则。有什么体面的方法来克服警告吗?