7

我只是在读这个线程: 简单的 C++ 指针转换

这让我想到为什么不允许不同指针类型之间的 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,那么基于指针不兼容的原因,可能不允许void* 到任何东西的 static_casting。(当然,从任何其他指针转换void* 总是可以的。)

那么为什么这些可能性之一不是真的——#2 和#3 要么都被允许,要么都不被允许?为什么它会像我的示例中所示那样工作?

4

3 回答 3

4
cs = static_cast<char*>( static_cast<void*>(ucs) ); // 3) now it's allowed!

它会编译。这是否意味着它是允许的?不是。该标准仅在通过 from 转换获得的情况下才允许从void*to转换,这不是您的情况。T*void*T*

于 2013-07-09T21:59:43.673 回答
1

问题是这样的:

my_type *p = new my_type;
void *vp = p; // okay

现在,如果您需要取回原始指针,请执行以下操作:

my_type *new_p = static_cast<my_type*>(vp); // okay

这很好,结果定义明确。如果您使用static_cast将指针转换为与原始指针不同的类型,则会出现未定义的行为,而这通常是编译器无法检测到的。所以演员表是允许的,如果你滥用它,它就在你的头上。

于 2013-07-09T22:44:45.430 回答
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*

是允许的,因为void* 进行强制转换有时是安全的,有时不是 - 编译器无法判断它在任何给定实例中是哪个......所以当你说“相信我,这是安全的”时,编译器相信你 - 如果你错了,那是在你的头上。面向对象

所以换句话说,你不能static_cast做一些永远不安全的事情——那是你需要的时候reinterpret_cast......但你可以 static_cast做一些有时安全有时不安全的事情(编译器无法判断在任何给定实例中是哪种情况) .

说了这么多……我在这里提到了很多“安全”和“不安全”,但这些词实际上是什么意思?(所以,在某种程度上,我什至不明白我自己在这里的答案......!如果你能帮我解决这个问题,请发表评论......)

于 2013-07-09T22:49:05.193 回答