次のコード (および VirtualAlloc()
がvoid*
を返すという事実を考慮する):
BYTE* pbNext = reinterpret_cast<BYTE*>(
VirtualAlloc(NULL, cbAlloc, MEM_COMMIT, PAGE_READWRITE));
なぜreinterpret_cast
の代わりにstatic_cast
が選択されるのですか?
reinterpret_cast
は大丈夫だと思っていました。整数型(例:DWORD_PTR
)との間でポインターをキャストしますが、void*
からBYTE*
にキャストするには、static_cast
で問題ありませんか?
この特定のケースに(微妙な?)違いがありますか、それとも両方とも有効なポインターキャストですか?
C++標準には、この場合の設定があり、他の方法の代わりに方法を提案していますか?
基本型への変換可能なポインターの場合、両方のキャストは同じ意味を持ちます。 static_cast
大丈夫だ。
一部のポインタタイプ間で変換する場合、ポインタに保持されている特定のメモリアドレスを変更する必要がある可能性があります。
そこで、2つのキャストが異なります。 static_cast
は適切な調整を行います。 reinterpret_cast
しない。
そのため、static_cast
ポインタタイプ間know that reinterpret_cast
が必要です。
_static_cast
_する必要があります。 暗黙の変換を取り消す場合は_static_cast
_を使用します。
ただし、この特定のケースでは、_void*
_から変換しているため、違いはありません。しかし、一般的に、2つのオブジェクトポインター間の_reinterpret_cast
_ ingは、次のように定義されます(§5.2.10/ 7):
オブジェクトポインターは、異なるタイプのオブジェクトポインターに明示的に変換できます。タイプ「_
T1
_へのポインター」のprvaluev
がタイプ "cv _T2
_へのポインター"に変換される場合、結果は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
_へのキャストは何も行いません。これは一般的には真実ではありません。これは ドリュー・ドーマンが言っていること :
_#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);
}
_
出力:
00CBFD5B
00CBFD5B
00CBFD5C
(y
は実際にはderived
を指していないため、これを使用することは未定義の動作です。)
ここで、_reinterpret_cast
_は、_void*
_を経由するため、異なる値になります。これが、可能な場合は_static_cast
_を使用し、必要な場合は_reinterpret_cast
_を使用する必要がある理由です。