この場合、実際には違いはありません。
ただし、複数の継承がある場合は違いがある可能性があります。
#include <cstdio>
struct A { int x; };
struct B { int y; };
struct C : B, A {};
int main() {
void* c = new C();
printf("%p\n", c); // 0x1000
printf("%p\n", (A*) c); // 0x1000
printf("%p\n", (A*) ((C*) c)); // 0x1004
return 0;
}
または、サブクラスには仮想メソッドがありますが、親には[1]ありません。これには、仮想継承[2]の使用が含まれます。
標準に関しては、OP は C スタイルのキャストを使用するため、この場合は と同等static_cast
です。
キャスト シーケンスB*
→ void*
→ B*
→A*
は有効です。最初の 2 つのキャストは、§5.2.9[expr.static.cast]/13 で要求されるのと同じポインターを返し、最後のキャストはポインター変換 §4.10[conv として機能します。 .ptr]/3.
ただし、キャスト シーケンスB*
→ void*
→A*
は実際には未定義の結果を返します。これは、結果が §5.2.9/13 で定義されていないためです ☺。
[1] :
#include <cstdio>
struct A { int x; };
struct C : A { virtual void g() {} };
int main() {
void* c = new C();
printf("%p\n", c); // 0x1000
printf("%p\n", (A*) c); // 0x1000
printf("%p\n", (A*) ((C*) c)); // 0x1008
return 0;
}
[2] :
#include <cstdio>
struct A { int x; };
struct C : virtual A {};
int main() {
void* c = new C();
printf("%p\n", c); // 0x1000
printf("%p\n", (A*) c); // 0x1000
printf("%p\n", (A*) ((C*) c)); // 0x1008
return 0;
}