C - 将指针指向void的指针

时间:2014-11-29 18:58:17

标签: c++ c pointers casting void

编辑我不需要问题的解决方案,我想知道是否以及为什么我应该更喜欢一件事而不是另一件事。功能声明无法更改

我有一个C ++项目,我需要编写一些代码,这些代码将由用C编写的代码调用。我有一个名为A的类,我需要实现一个破坏这样一个对象的方法由new分配,并使指针本身无效。

声明如下:

void destroy_A(void** a);

我需要void**,因此我可以取消*a

我应该使用以下哪种方式(如果有的话),以及为什么

delete *(A**)a;
delete *((A**)a);
delete (A*)*a;

编辑:也许我不清楚:我不知道技术术语,但我使用delete而不是free,实际的方法是通过C编译的代码调用的。否则,我不需要void**

这是我的CS教员要求,我没有写作业:)

2 个答案:

答案 0 :(得分:2)

所有这三个都有效。你在寻找什么,最终是

A* somePtr = ...; // get a pointer to your object
delete somePtr;   // delete the object it points to

您的三个选项将在下面复制,每个选项分为多行以突出显示他们正在做的事情:

delete *(A**)a;

A** ptrToPtrToA a = (A**)a;
A*  ptrToA a2 = *ptrToPtrTo_a;
delete ptrTo_a;

这里没问题。我们最终正确地解除引用对象

delete *((A**)a);

A** ptrToPtrTo_a = (A**)a;
A*  ptrTo_a = *ptrToPtrTo_a;
delete ptrTo_a;
嘿,这一个是完全一样的!括号的唯一作用是改变操作的顺序。你碰巧使用了“原生”顺序,所以括号什么都没做。

delete (A*)*a;

void* ptrTo_void = *a;
A*    ptrTo_a = (A*)ptrToVoid;
delete ptrTo_a;

这也很有效,它只是采取了不同的方式。

哪一个是正确的?这真的是一种风格选择。我将给你我的风格经验法则:总是在单独的行上投射无效指针。它使得发生的事情变得更加清晰。

A* myObject = (A*)*a; // I prefer this one in this case, but what matters...
delete myObject;      // ... is that it is distinct from the delete...
*a = 0;               // ...not which cast is "best."

我喜欢这样做,因为我发现当您真正开始使用时,向/从虚空中进行投射是一项非常棘手的业务。有很多地方可能会出错。我喜欢创建一个清晰的代码行,我可以在精神上分解我的所有演员,并确保它符合我的期望。因为我指定了我想要的变量的类型(myObjectA*,并且编译器无法做任何事情,否则如果我陷入困境),我更有可能得到编译器错误如果我做错了什么很容易从void编写强制转换,编译器默默地执行你没想到的转换。然后你正在修复运行时错误而不是编译时错误。

我也喜欢使用那个演员阵容作为发表评论的好地方解释为什么我认为首先进行演员表是安全的,例如“传递给唯一的无效指针”这个函数是我的函数在同一个.cpp文件中创建的函数,所以我确切知道哪个类型可以安全地转换为。“

答案 1 :(得分:1)

delete ptr 从不将在C中编译。如果是,第一个选项将是正确的,第二个选项将与它相同。