型変換(C ++)

1.はじめに

型変換の意味は、変数の型を別の型に変更することによって、変数の表現方法を変更することです。

2、C ++必須型変換

Cスタイルの強制は安全ではありません。

C ++の強制型変換:

  • 4つのキーワードstatic_cast、const_cast、reinterpret_cast、dynamic_castがC ++言語に追加されました。これらの4つのキーワードは、強制型変換に使用されます。
  • 新しいタイプの強制変換は、強制変換プロセスをより適切に制御できるため、さまざまなタイプの強制変換を制御できます。
  • C ++のスタイルはstatic_cast(content)です。C ++スタイルのキャストのもう1つの利点は、実行していることを明確に示すことができることです。プログラマーがそのようなコードを一瞥する限り、彼は強制の目的をすぐに知ることができます。

3つの具体的な紹介

1. static_cast:一般的な変換。データ型の強制変換に使用され、あるデータ型を別のデータ型に強制的に変換します。

	int a = 98;
	char c = static_cast<char>(a);
	cout << c << endl;// b

基本データ型ポインタ、オブジェクトポインタは変換できません。

	//基础数据类型指针
	int* p = NULL;
	char* sp = static_cast<char*>(p);//无效

	//对象指针
	Building* building = NULL;
	Animal* ani = static_cast<Animal*>(building);//无效



継承を使用してポインタまたは参照を変換できます

	//父类指针转成子类指针
	Animal* ani = NULL;
	Cat* cat = static_cast<Cat*>(ani);
	//子类指针转成父类指针
	Cat* soncat = NULL;
	Animal* anifather = static_cast<Animal*>(soncat);

	//还有具有继承关系的指针或者引用
	Animal aniobj;
	Animal& aniref = aniobj;
	Cat& cat = static_cast<Cat&>(aniref);

	Cat catobj;
	Cat& catref = catobj;
	Animal& anifather2 = static_cast<Animal&>(catref);	

2. dynamic_cast <type_id>(式)。継承関係のあるポインターまたは参照を変換する場合、変換前にオブジェクトタイプがチェックさ
れ、サブタイプからベースタイプへの変換が失敗する場合があります。

  1. 他の3つはコンパイル時に完了し、dynamic_castは実行時に処理され、型チェックは実行時に実行されます。

  2. 組み込みの基本データ型の強制には使用できません

    int a = 10;
    char c = dynamic_cast<char>(a);//无效
    
  3. dynamic_cast変換は、成功した場合はクラスへのポインターまたは参照を返し、変換が失敗した場合はNULLを返します。

  4. 変換にdynamic_castを使用する場合は、基本クラスに仮想関数が存在する必要があります。そうでない場合、コンパイルはパスしません。

    B中需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。

  5. クラスの変換では、クラスレベル間でアップストリーム変換を実行する場合、dynamic_castとstatic_castの効果は同じです。ダウンストリーム変換を実行する場合、dynamic_castにはタイプチェックの機能があり、static_castよりも安全です。

    アップコンバージョン、つまりサブクラスポインタが親ポインタを指している(通常は問題ありません)、メモリは大小です。ダウンコンバージョン、つまり親ポインタはサブクラスポインタに変換されますが、これは安全ではありません。ダウンコンバージョンの成功は、変換されるタイプにも関係します。つまり、変換されるポインタが指すオブジェクトの実際のタイプは、変換後のオブジェクトタイプと同じである必要があります。そうでない場合、変換は失敗します。 。

    C ++では、コンパイル時の型変換により、実行時にエラーが発生する可能性があります。特に、クラスオブジェクトのポインタ操作または参照操作が含まれる場合はそうです。Dynamic_cast演算子は、実行時に問題を引き起こす可能性のある型変換をテストできます。

	//非继承关系的指针
	Animal* ani = NULL;
	Building* building = dynamic_cast<Building*>(ani);//报错
	//具有继承关系指针
	Animal* ani = NULL;
	Cat* cat = dynamic_cast<Cat*>(ani);//报错  原因在于 dynamic做类型安全检查

	Cat* cat = NULL;
	Animal* ani = dynamic_cast<Animal*>(cat);

** 3、const_cast:** const qualifierは通常、変数を制限するために使用され、変数の値を変更できないことを示すために使用されます。const_castは、変更できないこの定数機能を強制的に削除するために使用されますが、 const_castは、変数の不変性を削除するためではなく、定数オブジェクトへのポインターまたは参照の不変性を削除するために使用されることに注意してください。不変性を削除するオブジェクトは、ポインターまたは参照である必要があります。

  1. 定数ポインターは強制的に非constポインターになり、元のオブジェクトを指します。
  2. 定数参照は強制的に非定数参照であり、元のオブジェクトを指します。
  3. 定数オブジェクトは、非定数オブジェクトに強制されます。
	//基础数据类型
	int a = 10;
	const int& b = a;	//b = 10;
	int& c = const_cast<int&>(b);
	c = 20;
	cout << "a:" << a << endl;//20
	cout << "b:" << b << endl;//20
	cout << "c:" << c << endl;//20

	const int a = 10;
	const int& pp = a;
	int& cc = const_cast<int&>(pp);
	cc = 100;
	

	//指针   增加或者去除变量的const性
	const int* p = NULL;
	int* p2 = const_cast<int*>(p);

	int* p3 = NULL;
	const int* p4 = const_cast<const int*>(p3);

4、 reinterpret_cast用法:reinterpret_cast <type_id>(式)

強制変換のためのreinterpret_castの主な目的は3つあります。

  1. ポインタまたは参照のタイプを変更し、
  2. ポインタまたは参照を十分な長さの整数に変換し、
  3. 整数型をポインタ型または参照型に変換します。

type-idは、ポインター、参照、算術型、関数ポインター、またはメンバーポインターである必要があります。

ポインターを整数に変換できます。また、整数をポインターに変換することもできます(最初にポインターを整数に変換し、整数を元のタイプのポインターに変換した後、元のポインター値を取得することもできます)。

reinterpret_castを使用する場合の強制変換プロセスはビットのコピーにすぎないため、使用中は特に注意する必要があります。

	//1. 无关的指针类型都可以进行转换
	Building* building = NULL;
	Animal* ani = reinterpret_cast<Animal*>(building);

	//2. 函数指针转换
	FUNC1 func1;
	FUNC2 func2 = reinterpret_cast<FUNC2>(func1);

4.結論

  • 変換する変数、変換前のタイプ、変換後のタイプ、および変換後の結果を明確に知っておく必要があります。
  • 一般に、型変換を回避するために型変換を使用することはお勧めしません。

おすすめ

転載: blog.csdn.net/weixin_45341339/article/details/111993677