Cas*_*ash 6 c++ pointers reference function void-pointers
为什么我不能通过void*参考传递?编译器允许我使用以下签名声明一个函数:
static inline void FreeAndNull(void*& item)
Run Code Online (Sandbox Code Playgroud)
但是当我尝试调用它时,我收到以下错误:
Error 1 error C2664: 'FreeAndNull' : cannot convert parameter 1 from 'uint8_t *' to 'void *&'
Run Code Online (Sandbox Code Playgroud)
将它投射到void*也不起作用
另外,有任何变通方法吗?
答案是肯定的,您可以通过void*引用传递,并且您获得的错误与此无关.问题是如果你有一个void*通过引用获取的函数,那么你只能传入实际上是void*s作为参数的变量.这是有充分理由的.例如,假设您有此功能:
void MyFunction(void*& ptr) {
ptr = malloc(137); // Get a block of raw memory
}
int* myIntArray;
MyFunction(myIntArray); // Error- this isn't legal!
Run Code Online (Sandbox Code Playgroud)
由于有明确的原因,上述代码是非法的.如果我们能传递myIntArray到MyFunction,它会得到重新分配指向型的缓冲区void*不是一个int数组.因此,从函数返回时,您int*将指向一个类型的数组void*,颠覆类型系统.这并不是说C++有一个强大的类型系统 - 它没有 - 但如果你要颠覆它,你必须明确地放置一些演员.
你同样不能这样做:
void MyFunction(void*& ptr) {
ptr = malloc(137); // Get a block of raw memory
}
int* myIntArray;
MyFunction((void*)myIntArray); // Error- this isn't legal!
Run Code Online (Sandbox Code Playgroud)
作为一个很好的参考,为什么你不能这样做,想想这个代码:
void OtherFunction(int& myInt) {
myInt = 137;
}
double myDouble;
OtherFunction((int)myDouble); // Also error!
Run Code Online (Sandbox Code Playgroud)
这是不合法的,因为如果你试图将double一个函数传递给一个函数int&,那么从那时起,int并且double具有根本不同的二进制表示,你最终会破坏double无意义数据的位.如果这个演员是合法的,就可以做这样的坏事.
所以简而言之,是的,你可以接受一个void* &,但如果你这样做,你必须传入真实void*的.正如Erik上面所指出的那样,如果你想要释放零指针模板是可行的方法.
如果你真的想传入uint_8*你的函数,你可以这样做:
uint_8* uPtr = /* ... */
void* ptr = uPtr;
FreeAndNull(ptr);
uPtr = (uint_8*) ptr;
Run Code Online (Sandbox Code Playgroud)
这需要显式转换来告诉编译器"是的,我知道这可能不安全,但无论如何我都会这样做."
希望这可以帮助!
如果您通过引用获取void*,则必须传递实际的void*,而不是uint8_t*.
试试这个:
template<typename T> inline void FreeAndNull(T * & V) { free(V); V = 0; }
Run Code Online (Sandbox Code Playgroud)
编辑:修改样本以更好地反映OP的函数名称,并解决@ 6502的完全正确的评论.
| 归档时间: |
|
| 查看次数: |
8017 次 |
| 最近记录: |