问题描述
void*
除了 C++ 中与内存分配相关的内容外,是否还需要?可以举个例子吗?
Is void*
necessary apart from memory allocation related stuff in C++?Can you give me an example?
推荐答案
记录内存地址
如果你想使用 iostreams 输出一个指针(例如用于日志记录),那么通过 void*
是确保 operator<<<
没有被以某种疯狂的方式超载.
Logging memory addresses
If you want to output a pointer using iostreams (e.g. for logging) then going via void*
is the only way of ensuring operator<<
hasn't been overloaded in some crazy way.
#include <iostream>
struct foo {
};
std::ostream& operator<<(std::ostream& out, foo*) {
return out<<"it's a trap!";
}
int main() {
foo bar;
foo *ptr = &bar;
std::cout << ptr << std::endl;
std::cout << static_cast<void*>(ptr) << std::endl;
}
测试 iostream 状态
iostreams 重载 operator void*
作为状态检查,这样像 if (stream)
或 while (stream)
这样的语法是一个简写测试流状态的方法.
Testing iostream status
iostreams overload operator void*
as a status check so that syntax like if (stream)
or while (stream)
is a short hand way of testing the stream status.
有时您可能希望将 void*
与模板元编程一起使用,作为减少的全部内容,例如使用 SFINAE 技巧,但通常有一种更好的方法可以使用一种或另一种形式的部分特化.
You might want to use void*
with template metaprogramming sometimes as a reduced catch all, e.g. with SFINAE tricks, but more often than not there's a nicer way around it using a partial specialisation of one form or another.
正如 Alf 在评论中指出的那样,dynamic_cast
对于获取层次结构中最派生的类型也很有用,例如:
As Alf pointed out in the comments dynamic_cast<void*>
is also useful for getting at the most derived type in a heirarchy, e.g.:
#include <iostream>
struct other {
virtual void func() = 0;
int c;
};
struct foo {
virtual void func() { std::cout << "foo" << std::endl; }
int a;
};
struct bar : foo, other {
virtual void func() { std::cout << "bar" << std::endl; }
int b;
};
namespace {
void f(foo *ptr) {
ptr->func();
std::cout << ptr << std::endl;
std::cout << dynamic_cast<void*>(ptr) << std::endl;
}
void g(other *ptr) {
ptr->func();
std::cout << ptr << std::endl;
std::cout << dynamic_cast<void*>(ptr) << std::endl;
}
}
int main() {
foo a;
bar b;
f(&a);
f(&b);
g(&b);
}
给出:
foo
0xbfb815f8
0xbfb815f8
bar
0xbfb815e4
0xbfb815e4
bar
0xbfb815ec
0xbfb815e4
在我的系统上.
§ 15.3.1 规定:
§ 15.3.1 states:
异常声明不应表示指向的指针或引用不完整的类型,除了 void*、const void*
、volatile void* 或const volatile void*.
因此,捕获指向不完整类型的指针的唯一合法方法似乎是通过 void*
.(虽然我认为如果你真的需要使用它可能会有更大的问题)
So it seems to be the only legal way of catching a pointer to an incomplete type is via void*
. (Although I think there's possibly bigger issues if you actually needed to use that)
void*
有很多传统"C 用于存储指向数据的指针而不知道它是什么,但在新的 C++ 代码中几乎总是有更好的表达方式功能.
There are a lot of "legacy" C uses for void*
for storing pointers to data without knowing what it is, but in new C++ code there is almost always a better way of expressing the same functionality.
这篇关于除了内存分配相关的东西之外,void* 是否必要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!