C++クラスオブジェクトの強制型変換

3319 ワード

クラス継承構造:
class AClass {
public:
  virtual ~AClass() = default;

  int func_a() {
    printf("func_a in AClass this %p
", this); return 0; } virtual int func_b() = 0; private: int inta = 0; }; class DClass { public: virtual ~DClass() = default; int func_d() { printf("func_d in DClass this %p
", this); return 0; } private: int intd = 0; }; class BClass : public AClass { public: virtual ~BClass() = default; virtual int func_a() { printf("func_a in BClass
"); return 0; } private: int intb = 0; }; class CClass : public BClass, public DClass { public: virtual ~CClass() = default; int func_a() override { printf("func_a in CClass this %p
", this); AClass::func_a(); func_d(); return 0; } int func_b() override { printf("func_b in CClass
"); return 0; } private: int intb = 0; };

テストコードは次のとおりです.
void test_func() {
  CClass c;
  c.func_a();
  CClass *pc = &c;
  BClass *pb = &c;
  AClass *pa = &c;
  DClass *pd = &c;

  BClass *pb_static_cast = static_cast(pc);
  AClass *pa_static_cast = static_cast(pc);
  DClass *pd_static_cast = static_cast(pc);

  BClass *pb_reinterpret_cast = reinterpret_cast(pc);
  AClass *pa_reinterpret_cast =  reinterpret_cast(pc);
  DClass *pd_reinterpret_cast =  reinterpret_cast(pc);

  printf("pc %p, pa %p, pa_static_cast %p, pa_reinterpret_cast %p
", pc, pa, pa_static_cast, pa_reinterpret_cast); printf("pc %p, pb %p, pb_static_cast %p, pb_reinterpret_cast %p
", pc, pb, pb_static_cast, pb_reinterpret_cast); printf("pc %p, pd %p, pd_static_cast %p, pd_reinterpret_cast %p
", pc, pd, pd_static_cast, pd_reinterpret_cast); }

上記のコードがコンパイルされると、コンパイラはDClass *pd_reinterpret_cast = reinterpret_cast(pc);行に対して次のwarningを報告します.
test.cpp:85:34: warning: 'reinterpret_cast' from class 'CClass *' to its base at non-zero offset 'DClass *' behaves differently from 'static_cast' [-Wreinterpret-base-class]
  DClass *pd_reinterpret_cast =  reinterpret_cast(pc);
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:85:34: note: use 'static_cast' to adjust the pointer correctly while upcasting
  DClass *pd_reinterpret_cast =  reinterpret_cast(pc);
                                 ^~~~~~~~~~~~~~~~
                                 static_cast
1 warning generated.


上のコード実行時には、端末に次のような出力があります.
func_a in CClass this 0x7fff859533c0
func_a in AClass this 0x7fff859533c0
func_d in DClass this 0x7fff859533d0
pc 0x7fff859533c0, pa 0x7fff859533c0, pa_static_cast 0x7fff859533c0, pa_reinterpret_cast 0x7fff859533c0
pc 0x7fff859533c0, pb 0x7fff859533c0, pb_static_cast 0x7fff859533c0, pb_reinterpret_cast 0x7fff859533c0
pc 0x7fff859533c0, pd 0x7fff859533d0, pd_static_cast 0x7fff859533d0, pd_reinterpret_cast 0x7fff859533c0

注意多重継承の場合、サブクラスポインタ強制タイプをベースクラスポインタに変換した場合のstatic_castreinterpret_castの動作の違い.