为什么我可以使用 static_cast 与 void* 而不是与字符*
Why can I use static_cast With void* but not With char*
我知道reinterpret_cast
主要用于往返char*
。
但我惊讶地发现static_cast
可以用void*
做同样的事情。例如:
auto foo "hello world"s;
auto temp = static_cast<void*>(&foo);
auto bar = static_cast<string*>(temp);
我们从使用reinterpret_cast
和char*
而不是static_cast
和void*
中获得什么?这与严格的混叠问题有关吗?
一般来说,如果其中一个可以隐式转换为另一个类型,static_cast
将强制转换任何两种类型。这包括算术转换、向下转换、向上转换和往返void*
的转换。
也就是说,如果此强制转换有效:
void foo(A a);
B b;
foo(b);
然后,static_cast<B>(a)
和static_cast<A>(b)
也将有效。
由于任何指针都可以隐式投射到 void*
,因此您的特殊行为。
reinterpret_cast
通过重新解释值的位模式来强制转换。正如您在问题中所说,这通常是为了在不相关的指针类型之间进行转换。
是的,您可以使用两个static_cast
通过 void*
在不相关的指针类型之间进行转换:
B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!
但这正在扭曲规则。如果您真的需要这个,只需使用reinterpret_cast
。
你的问题实际上有两个部分:
- 我是否应该使用
static_cast
或reinterpret_cast
来处理指向对象基础位模式的指针,而不考虑对象类型? - 如果我应该使用
reinterpret_cast
是void*
还是char*
更可取来解决这种底层位模式?
static_cast
:使用隐式转换和用户定义转换的组合在类型之间进行转换
在 5.2.9[expr.static.cast]13 中,标准实际上给出了以下示例:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
它利用隐式强制转换:
指向任何(可选 cv 限定的(对象类型的 prvalue 指针
T
可以转换为指向(相同 cv 限定的(void
的 prvalue 指针。生成的指针表示与原始指针值在内存中相同的位置。如果原始指针是空指针值,则结果是目标类型的空指针值。*
但是,从类型 T
的指针到char*
没有隐式强制转换。因此,完成该演员的唯一方法是使用reinterpret_cast
。
reinterpret_cast
:通过重新解释底层位模式在类型之间进行转换
因此,在回答问题的第 1 部分时,当您转换为您希望使用底层位模式的void*
或char*
时, 应该使用reinterpret_cast
,因为它的使用向读者表示与底层位模式之间的转换。
接下来,让我们将void*
与char*
进行比较。这两者之间的决定可能更多地依赖于应用程序。如果要将标准库函数与底层位模式一起使用,只需使用函数接受的类型:
-
void*
用于cstring
库中提供的mem
函数 -
read
和write
使用char*
作为输入
值得注意的是,C++特定的库更喜欢char*
来指向内存。出于兼容性原因,将内存保留为void*
似乎已被保留为此处的指针。因此,如果 cstring
库函数不会用于您的底层位父级,请使用C++特定库行为来回答问题的第 2 部分:首选char*
而不是void*
。
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 我的字符计数代码计算错误.为什么
- 字符串-C++后显示的随机字符
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在c++类上调用void函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 在带有 (void*) 强制转换的字符串中打印字符的内存地址
- 如何将字符*附加到void*的末端
- 将 void (*)() 转换为 void (*)(无符号字符)
- 视觉工作室中涉及 void*、字符串和常量字符 [] 的意外重载解决方案
- 在 C 中,我可以将 void* 分配给字符*,但不能在 C++ 中分配
- 从“void*”到“无符号字符*”的转换无效
- reinterpret_cast<字符*>(p)或static_cast<字符*>((void*)p))表示字节指针差,哪个更好?
- 正在将内存分配给二维字符数组,错误:从“void*”到“char**”的转换无效
- 从"void"转换为非标量类型"std::p air<std::basic_string<字符,std::char_traits<char>
- 为什么我可以使用 static_cast 与 void* 而不是与字符*
- 视觉 任何非(字符*)正确的方法,用于从 C++ 中的常量字符串初始化 void*