我对reinterpret_castvs 的适用性感到困惑static_cast.从我读到的一般规则是使用静态转换,当类型可以在编译时解释,因此这个词static.这是C++编译器内部用于隐式转换的转换.
reinterpret_casts适用于两种情况,将整数类型转换为指针类型,反之亦然,或将一种指针类型转换为另一种指针类型.我得到的一般想法是不可移植的,应该避免.
我有点困惑的地方是我需要的一种用法,我从C调用C++并且C代码需要保持C++对象,所以基本上它拥有一个void*.什么演员应该用于在void *类型和类型之间进行转换?
我看过两者的用法static_cast和reinterpret_cast?虽然从我读过的内容看起来似乎static更好,因为演员阵容可以在编译时发生?虽然它说用于reinterpret_cast从一种指针类型转换为另一种指针类型?
说我想投A*,char*反之亦然,我们有两个选择(我的意思是,我们很多人认为我们有两个选择,因为两者似乎都有效!因此混乱!):
struct A
{
int age;
char name[128];
};
A a;
char *buffer = static_cast<char*>(static_cast<void*>(&a)); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2
Run Code Online (Sandbox Code Playgroud)
两者都很好.
//convert back
A *pA = static_cast<A*>(static_cast<void*>(buffer)); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2
Run Code Online (Sandbox Code Playgroud)
即便这样工作正常!
那么,为什么我们reinterpret_cast在C++中有两个链接 static_cast可以完成它的工作呢?
你们中的一些人可能认为这个主题与之前的主题重复,例如本文底部列出的,但事实并非如此.这些主题讨论只在理论上,但他们没有给出甚至一个例子来展示为什么reintepret_cast是真正需要的,而2 static_cast将肯定会失败.我同意,一个static_cast会失败.但两个怎么样?
如果两个链接的语法static_cast看起来很麻烦,那么我们可以编写一个函数模板,使其对程序员更友好:
template<class To, class From>
To any_cast(From v)
{
return static_cast<To>(static_cast<void*>(v));
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以使用它,如:
char *buffer = any_cast<char*>(&a); …Run Code Online (Sandbox Code Playgroud) #include <iostream>
int main(int argc, char * argv[])
{
int a = 0x3f800000;
std::cout << a << std::endl;
static_assert(sizeof(float) == sizeof(int), "Oops");
float f2 = *reinterpret_cast<float *>(&a);
std::cout << f2 << std::endl;
void * p = &a;
float * pf = static_cast<float *>(p);
float f3 = *pf;
std::cout << f3 << std::endl;
float f4 = *static_cast<float *>(static_cast<void *>(&a));
std::cout << f4 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我从可靠的编译器中获得以下信息:
me@Mint-VM ~/projects $ g++-5.3.0 -std=c++11 -o pun pun.cpp -fstrict-aliasing -Wall
pun.cpp: In function ‘int main(int, …Run Code Online (Sandbox Code Playgroud) 这困扰了我很长时间:如何进行从任何东西char *到将二进制文件转储到磁盘的指针转换。
在C语言中,您甚至无需考虑。
double d = 3.14;
char *cp = (char *)&d;
// do what u would do to dump to disk
Run Code Online (Sandbox Code Playgroud)
但是,在C ++中,每个人都说C-cast不被接受,我一直在这样做:
double d = 3.14;
auto cp = reinterpret_cast<char *>(&d);
Run Code Online (Sandbox Code Playgroud)
现在这是从cppreference复制的,所以我认为这是正确的方法。
但是,我从多个消息来源读到这是UB。(例如,这个)所以我不禁要问是否有任何“ DB”方式(根据那篇文章,没有)。
我经常遇到的另一种情况是实现这样的API:
void serialize(void *buffer);
Run Code Online (Sandbox Code Playgroud)
您将在其中将很多东西转储到此缓冲区。现在,我一直在这样做:
void serialize(void *buffer) {
int intToDump;
float floatToDump;
int *ip = reinterpret_cast<int *>(buffer);
ip[0] = intToDump;
float *fp = reinterpret_cast<float *>(&ip[1]);
fp[0] = floatToDump;
}
Run Code Online (Sandbox Code Playgroud)
好吧,我想这也是UB。
现在,真的没有“ DB”方法可以完成这两项任务吗?我见过有人uintptr_t用来完成类似于sth的serialize任务,将指针与一起作为整数数学sizeof …