关于c ++:将void指针转换为特定类型指针时,哪个转换符号更好,static_cast还是reinterpret_cast?

When convert a void pointer to a specific type pointer, which casting symbol is better, static_cast or reinterpret_cast?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Should I use static_cast or reinterpret_cast when casting a void* to whatever

在这个程序中,我有一个void *作为参数,并希望将其强制转换为特定的类型。但我不知道该用哪种"铸造符号"。static_castreinterpret_cast都工作。哪一个更好?标准C++推荐哪一种?

1
2
3
4
5
6
7
8
9
10
typedef struct
{
    int a;
}A, *PA;

int foo(void* a)                // the real type of a is A*
{
    A* pA = static_cast<A*>(a); // or A* pA = reinterpret_cast<A*>(a);?
    return pA->a;
}

这里是

1
A* pA = static_cast<A*>(a);

1
A* pA = reinterpret_cast<A*>(a);

更合适?


static_cast更适合将void*转换为其他类型的指针。

当两种类型之间有一种自然、直观的转换时,static_cast是一种选择类型,这不一定保证在运行时工作。例如,可以使用static_cast将基类指针转换为派生类指针,这种转换在某些情况下是有意义的,但在运行时才能验证。同样,您可以使用static_castint转换为char,这是一种定义明确的方法,但在执行时可能会导致精度损失。

另一方面,reinterpret_cast是一个铸造操作员,设计用于进行根本不安全或不可携带的转换。例如,您可以使用reinterpret_castvoid *转换为int,如果您的系统恰好有sizeof (void*)&le;sizeof (int),它将正常工作。您还可以使用reinterpret_castfloat*转换为int*,反之亦然,这是平台特定的,因为floatint的特定表示不能保证彼此有任何共同点。

简而言之,如果您发现自己正在进行一个转换,在这种转换中,强制转换在逻辑上有意义,但在运行时可能不一定成功,请避免使用reinterpret_cast。如果您事先知道强制转换将在运行时运行,并与编译器通信,"我知道这可能不起作用,但至少它是有意义的,并且我有理由相信它在运行时会正确地执行正确的操作",那么static_cast是一个很好的选择。然后,编译器可以检查强制转换是否在相关的如果不是这样,则报告编译时错误。使用reinterpret_cast进行指针转换可以完全绕过编译时安全检查。

在某些情况下,您可能希望使用dynamic_cast而不是static_cast,但这些大多涉及类层次结构中的强制转换,并且(很少)直接涉及void*

至于规范首选哪一种,也没有过分提到"正确使用"(或者至少我不记得有一种是这样提到的)但是,我认为规范希望您使用static_cast而不是reinterpret_cast。例如,当使用C样式的强制转换时,如

1
A* ptr = (A*) myVoidPointer;

试过的铸造操作员的命令总是试图在reinterpret_cast之前使用static_cast,这是您想要的行为,因为reinterpret_cast不能保证是可移植的。


为此,请使用static_cast。只有在最罕见的情况下,没有其他方法使用reinterpret_cast


如果要沿类层次结构强制转换,请使用dynamic_cast—它检查以确保实际对象与要强制转换的类型兼容。


你很可能通过隐式转换得到了void*,所以你应该使用static_cast,因为它最接近隐式转换。


reinterpret_cast将强制将void*转换为目标数据类型。它不能保证任何安全,并且您的程序可能崩溃,因为底层对象可能是任何东西。

例如,您可以将myclass*类型转换为void*类型,然后使用reinterpret_cast将其转换为yourclass*,这可能具有完全不同的布局。

所以最好还是使用static_cast


两者都不。为什么你要首先传递一个指向虚空的指针?在C中,由于缺少选择,这是相当常见的,但是在C++中,几乎没有理由这样做。

编辑:@dan o提高了使用强制转换最小化生成代码的可能性。对于任何不太了解他所说内容的人来说,考虑一下像std::vector--当你定义(例如)std::vectorstd::vector时,你通常会得到一个完全独立的代码,即使两者都只是存储指针,所以它们可以共享相同的代码。通过定义一个只保存void *s的容器,并在从容器中检索项目时将其转换回正确的类型,可以绕过这一点。

首先,这通常是一个过早的优化,充其量(而且往往会被证明是一个对峙)。尽管如此,有时候还是有道理的。但是,当它执行此操作时,您希望将强制转换限制在一个位置,但要创建一个模板化的前端到void *的伪通用容器:

1
2
3
4
5
6
template <class T>
pointer_container {
    std::vector <void *> data;
public:
    T *operator[](size_t index) { return static_cast<T *>(data[index]); }
};

现在,我们确实有了演员阵容。是的,为了直接回答最初的问题,在这种情况下,使用static_cast是正确的。

在MS-DOS(例如)的时代,这种代码相当常见。然而,今天,这种类型的代码是完全没有意义的。

现在,操作人员已经说他被一个固定的接口卡住了,而实现它是他的工作。我不知道他在哪里工作,也不知道他和谁一起工作,我也没有看到其他代码可以用,所以我不能肯定地说,他们所做的工作设计不好,应该改变。奥思,根据我过去的经验,我想情况至少是99%。因此,我坚持我原来的回答。刚刚贴出的答案说"静态演员表",没有任何关于避免演员表的内容,这些答案真的是无益的。虽然这是几乎不可能的演员真的无法避免,只是假设它的理由是错误的反应和一个坏的答案。

我会更进一步:如果一个关于演员阵容的问题不能提供关于为什么演员阵容不可避免的证据,那么任何人都应该认为"好"的唯一建议就是建议完全消除演员阵容。这可能(在极少数情况下)证明了演员阵容是无法避免的——但这绝对是例外,而不是规则。