Mr.*_*C64 47 c++ pointers casting static-cast reinterpret-cast
考虑以下代码(以及VirtualAlloc()返回avoid*的事实):
BYTE* pbNext = reinterpret_cast<BYTE*>(
VirtualAlloc(NULL, cbAlloc, MEM_COMMIT, PAGE_READWRITE));
Run Code Online (Sandbox Code Playgroud)
为什么reinterpret_cast选择而不是static_cast?
我以前认为reinterpret_cast可以用于例如从整数类型(例如DWORD_PTR)转换指针,但是从a转换void*为a BYTE*,是不是static_cast可以?
在这种特殊情况下是否存在任何(微妙的?)差异,或者它们是否只是有效的指针转换?
C++标准是否偏爱这种情况,建议采用一种方式而不是另一种方式?
Dre*_*ann 39
对于基本类型的可转换指针,两个转换具有相同的含义; 所以你是对的,static_cast没关系.
在某些指针类型之间进行转换时,指针中保存的特定内存地址可能需要更改.
这就是两个演员的不同之处. static_cast会做出适当的调整. reinterpret_cast将不会.
因此,static_cast除非您知道需要,否则指针类型之间的一般规则是很好的reinterpret_cast.
GMa*_*ckG 23
你应该static_cast.用于static_cast撤消隐式转换的情况.
然而,在这种特殊情况下,没有区别,因为你正在转换void*.但一般来说,reinterpret_cast两个对象指针之间的定义是(§5.2.10/ 7):
可以将对象指针显式转换为不同类型的对象指针.当prvalue
v类型的"指针T1"被转换为类型"指向cvT2",其结果是static_cast<cv T2*>(static_cast<cv void*>(v)),如果这两个T1和T2是标准布局类型和的对准要求T2并不比那些更严格的T1,或者如果任一类型是void.将"指向T1"的类型的prvalue转换为"指向"的类型T2(其中T1和T2是对象类型,并且对齐要求T2不比那些更严格T1)并返回其原始类型,产生原始指针值.任何其他此类指针转换的结果都是未指定的.
强调我的.既然T1你已经是void*,中投以void*在reinterpret_cast不执行任何操作.总的来说这不是真的,这就是Drew Dormann所说的:
#include <iostream>
template <typename T>
void print_pointer(const volatile T* ptr)
{
// this is needed by oversight in the standard
std::cout << static_cast<void*>(const_cast<T*>(ptr)) << std::endl;
}
struct base_a {};
struct base_b {};
struct derived : base_a, base_b {};
int main()
{
derived d;
base_b* b = &d; // implicit cast
// undo implicit cast with static_cast
derived* x = static_cast<derived*>(b);
// reinterpret the value with reinterpret_cast
derived* y = reinterpret_cast<derived*>(b);
print_pointer(&d);
print_pointer(x);
print_pointer(y);
}
Run Code Online (Sandbox Code Playgroud)
输出:
00CBFD5B
00CBFD5B
00CBFD5C
(注意,因为y实际上并不指向a derived,使用它是未定义的行为.)
在这里,reinterpret_cast提出了一个不同的价值,因为它经历了void*.这就是为什么你应该尽可能使用static_cast,reinterpret_cast何时必须使用.
用static_cast一个指针转换为和void*保证保留地址.
reinterpret_cast 另一方面,保证如果将指针从一种类型转换为另一种类型,并返回原始类型,则保留地址.
虽然对于大多数实现,您会看到使用其中任何一个的相同结果,static_cast应该是首选.
而且C++11我记得,使用reinterpret_castfor void*有一个明确定义的行为.在此之前,此行为被禁止.
It is not permitted to use reinterpret_cast to convert between pointers to object type and pointers to void.
Run Code Online (Sandbox Code Playgroud)
拟议决议(2010年8月):
更改5.2.10 [expr.reinterpret.cast]第7段如下:
可以将对象指针显式转换为不同类型的对象指针.当"指向T1的指针"类型的prvalue v转换为"指向cv T2的指针"类型时,如果T1和T2都是标准布局类型,则结果为static_cast(static_cast(v))(3.9 [basic.types]并且T2的对齐要求不比T1更严格,或者如果任何一种类型无效.
将"指向T1的指针"类型的prvalue转换为"指向T2的指针"类型(其中T1和T2是对象类型,T2的对齐要求不比T1更严格)并返回其原始类型会产生原始类型指针值.未指定任何其他此类指针转换的结果.
更多信息在这里.
感谢Jesse Good提供的链接.
| 归档时间: |
|
| 查看次数: |
52493 次 |
| 最近记录: |