読者です 読者をやめる 読者になる 読者になる

実行時型情報(Run-time Type Identification: RTTI)

ようは実行時にオブジェクトの情報をゲットするための仕組み(だとおもう).

JavaでいうとClassのforNameとかみたいなことをするためにあるのかな??

typeid

オブジェクトの情報を取得できる.

type_info& typeid(Object);
type_info型の参照を返す.

型の情報を取得できる.

type_info& typeid(Type-Name);
これを基準に型比較が可能


間接参照するポインタがNULLの場合例外が投げられる.
投げられる例外は,
bad_typeid

#incude
をつかう.

#include <iostream>
#include <typeinfo>

using namespace std;

class B{
  virtual void f(){}
};

class D1: public B{
  void f() {}
};
class D2: public B{
  void f() {}
};

int main(){
  B* p;

  B objB;
  D1 objD1;
  D2 objD2;

  p = &objB;
  if(typeid(*p) == typeid(D2)){
    cout << "このオブジェクトはD2です." << endl;
  }else{
    cout << "このオブジェクトはD2ではありません." << endl;
  }

  p = &objD1;
  if(typeid(*p) == typeid(D2)){
    cout << "このオブジェクトはD2です." << endl;
  }else{
    cout << "このオブジェクトはD2ではありません." << endl;
  }

  p = &objD2;
  if(typeid(*p) == typeid(D2)){
    cout << "このオブジェクトはD2です." << endl;
  }else{
    cout << "このオブジェクトはD2ではありません." << endl;
  }
  return 0;
}

dynamic_cast

  • ある型のポインタを別のポインタに変換する
  • ある型の参照を別の参照に変換する

投げられる例外
bad_cast
ポインタのキャスト時に失敗してもNULLが返ってくるだけ.
参照のキャスト時には例外が投げられる.

#include <iostream>
using namespace std;

class B{
  virtual void f(){}
};

class D1: public B{
  void f(){}
};

class D2: public B{
  void f(){}
};

int main(){
  B* p;
  D1 ob;

  //ポインタのキャスト失敗はNULLが帰ってくるだけ
  cout << "ポインタのキャスト失敗はNULLが帰ってくるだけ" << endl;
  try{
    p = dynamic_cast<D2*>(&ob);
  }catch(bad_cast& bc){
    cout << "Catch!! キャスト失敗" << endl;
    cout << bc.what() << endl;
  }
  if(!p){
    cout << "値はNULL:ぬるぽ." << endl;
  }

  //参照のキャスト失敗はbad_casが帰ってくる
  cout << "参照のキャスト失敗はbad_casが帰ってくる" << endl;
  try{
    D2& obRef = dynamic_cast<D2&>(ob);
  }catch(bad_cast& bc){
    cout << "Catch!! キャスト失敗" << endl;
    cout << bc.what() << endl;
  }
  if(!p){
    cout << "値はNULL:ぬるぽ." << endl;
  }

  return 0;
}

typeidみたいに型チェックにも使える.
MyClass*型にcastできる時だけ表示する.

    // ポインタpがMyClass型のポインタに変換できる時だけ...
    // つまり,pがMyClass型のポインタである場合だけtrueになる
    if(dynamic_cast<MyClass*>(p))
      p->example();
  }
  return 0;                                                           

const_cast

constやvolatileを上書きできる.
一般的な用途はconstを取り除くこと...いいの?

そもそも,volatileってなんだ..
揮発性の...っていみらしい.
メモリ?
付ける意味は

処理系で行われる最適化を抑制する

ことらしい.

#include <iostream>                     
using namespace std;

void stripConst(const int* p){
  int* num;
  
  num  = const_cast<int*>(p);
  *num = 123;
}

int main(){
  int num=10;
  
  cout << "num=" << num << endl;
  stripConst(&num);
  cout << "num=" << num << endl;
  
  return 0; 
}

参考

static_cast

独習C++,Teach yourself C++によると

ポリモーフィック型変換を行います。

基本クラスポインタを派生クラスポインタ

にするらしい.
ダウンキャストってこと?
....いいの?

#include <iostream>
using namespace std;

int main(){
  int intNum;
  double doubleNum = 11.23;

  cout << "Double: " << doubleNum << endl;
  intNum  = static_cast<int>(doubleNum);
  cout << "Integer: " << intNum << endl;

  return 0;
}

reinterprent_cast

再解釈するという意味らしい.
ポインタ->int
int->ポインタ
の変換とか

本質的に互換性のないポインタ型間での型変換に使用します。

ほー.