我刚读这个帖子: Simple c++ pointer casting
这让我想到为什么不允许不同指针类型之间的static_cast(除非在它的情况下除外)除非你static_cast到void *作为中间步骤。在我看来,无论是两者还是两者都不应该被允许。这是一个例子:
char* cs;
unsigned char* ucs;
cs = reinterpret_cast<char*>(ucs); // 1) allowed, of course
cs = static_cast<char*>(ucs); // 2) not allowed: incompatible pointer types
cs = static_cast<char*>( static_cast<void*>(ucs) ); // 3) now it's allowed!
在我看来,如果#3可行,那么也应该允许#2。或者相反,如果由于指针不兼容(需要reinterpret_cast)而不允许#2,则可能由于指针不兼容而不允许static_casting 从一个void *到任何东西。 (当然,将转换为来自任何其他指针的void *总是可以的。)
那么为什么这些可能性中没有一个是真的 - #2和#3既可以允许也可以不允许?为什么它会像我的例子中所示那样工作?
答案 0 :(得分:4)
cs = static_cast<char*>( static_cast<void*>(ucs) ); // 3) now it's allowed!
它会编译。这是否意味着允许?不。该标准仅允许从void*
到T*
的转化,只有在void*
转换获得T*
的情况下,这不是您的情况。
答案 1 :(得分:1)
问题在于:
my_type *p = new my_type;
void *vp = p; // okay
现在,如果您需要返回原始指针,请执行以下操作:
my_type *new_p = static_cast<my_type*>(vp); // okay
没关系,结果很明确。如果使用static_cast
将指针转换为不同的类型而不是原始指针,则会得到未定义的行为,而这通常不会被编译器检测到。所以演员是允许的,如果你误用它,它就在你的头上。
答案 2 :(得分:1)
好的,我会在这里回答我自己的问题,因为我觉得我有了一个想法,虽然我不确定它是对的。如果你认为我通过上/下投票得到它我可以告诉我,我想。 :)
所以我认为static_cast
告诉编译器,“相信我,这是安全的。”而reinterpret_cast
告诉编译器,“我知道这是不安全的;无论如何都要这样做。”
回到我的例子:
cs = reinterpret_cast<char*>(ucs);
是不安全的,但编译器仍会这样做,因为你告诉它。
cs = static_cast<char*>(ucs);
会导致编译错误,因为你说,“相信我,这是安全的”,但编译器知道它确实不是。所以它不信任你,因为它在这种情况下实际上知道,因此也就是错误。
现在最后一个例子有两个部分:
void* temp = static_cast<void*>(ucs);
当然是允许的,因为将转换为 void *是安全的。
cs = static_case<char*>(temp); // remember temp is a void*
是允许的,因为从转换有时是安全的,有时候不是 - 编译器无法分辨它在任何给定的实例中...所以当你说“相信我,这是安全,“编译器信任你 - 如果你错了,那就在你的头上。 O.O
换句话说,你不能static_cast
一些从不安全的事情 - 那时你需要reinterpret_cast
......但你可以 static_cast
有时安全且有时不安全的东西(并且编译器无法分辨任何给定实例中的情况)。
所有这一切......我指的是“安全”和“不安全”在这里投下很多,但这些话究竟是什么意思呢? (所以,在某种程度上,我仍然不理解我自己的答案......!如果你可以帮我解决这个问题,请发表评论......)