C++のstatic_castとdynamic_castの違いと使い分けを徹底解説
static_castとは
static_castは、通常の型変換に使用されるキャストです。コンパイラが行う暗黙の型変換(implicit type coercion)も担当しており、明示的に記述することも可能です。floatからint、charからintへの変換のように、基本的な数値型同士の変換に適しています。また、継承関係にあるクラス間のポインタ変換にも利用できます。ただし、互換性のない型同士の変換を試みると、コンパイル時にエラーが発生します。
コード例
#include<iostream>
using namespace std;
class Base {};
class Derived : public Base {};
class MyClass {};
main(){
Derived* d = new Derived;
Base* b = static_cast<Base*>(d); // この行は正常に動作する
MyClass* x = static_cast<MyClass*>(d); // コンパイル時にERRORが生成される
}
出力結果
[Error] invalid static_cast from type 'Derived*' to type 'MyClass*'
上記の例では、Derived*からBase*への変換は継承関係があるため問題なく成功します。一方、継承関係にないMyClass*への変換は無効な操作とみなされ、コンパイルエラーとなります。
dynamic_castとは
dynamic_castは、ポリモーフィズム(多態性)を扱うために使用されるキャストです。このキャストを使用するのは、派生クラスへキャストする場合のみです。つまり、継承関係において基底クラスから派生クラスへキャストする(ダウンキャストする)際に専用で使われます。実行時に実際のオブジェクトの型がチェックされ、キャストが失敗した場合はヌルポインタが返されるため、安全な型変換を実現できます。
コード例
#include<iostream>
using namespace std;
class MyClass1 {
public:
virtual void print()const {
cout << "This is from MyClass1\n";
}
};
class MyClass2 {
public:
virtual void print()const {
cout << "This is from MyClass2\n";
}
};
class MyClass3: public MyClass1, public MyClass2 {
public:
void print()const {
cout << "This is from MyClass3\n";
}
};
int main(){
MyClass1* a = new MyClass1;
MyClass2* b = new MyClass2;
MyClass3* c = new MyClass3;
a -> print();
b -> print();
c -> print();
b = dynamic_cast< MyClass2*>(a); // このキャストは失敗する
if (b)
b->print();
else
cout << "no MyClass2\n";
a = c;
a -> print(); // MyClass3から出力される
b = dynamic_cast< MyClass2*>(a); // キャストに成功
if (b)
b -> print();
else
cout << "no MyClass2\n";
}
出力結果
This is from MyClass1 This is from MyClass2 This is from MyClass3 no MyClass2 This is from MyClass3 This is from MyClass3
この例では、最初にMyClass1型のポインタaをMyClass2型へキャストしようとした処理は失敗し、「no MyClass2」が出力されます。これはaが実際にはMyClass2と無関係なオブジェクトを指しているためです。その後、aにMyClass3のインスタンスを代入してから再度キャストすると、MyClass3はMyClass2を継承しているため今度は成功し、正しくMyClass3のメソッドが呼び出されます。
-
C++のキャスト演算子を使い分けよう!static_cast・dynamic_cast・const_cast・reinterpret_castの違いと使いどころ
C++には、C言語形式のキャストとは異なる4種類のキャスト演算子が用意されています。それぞれ目的と安全性が異なるため、状況に応じて適切に使い分けることが重要です。本記事では、const_cast、static_cast、dynamic_cast、reinterpret_castのそれぞれの役割と使用場面を詳しく解説します。 const_cast:const性(定数性)の追加・除去 const_castは、変数に対してconstを取り除いたり、逆に追加したりするための専用キャストです。const指定された変数から定数性を外す必要がある場合や、定数性を付与したい場合に使用します。 ただし、本来書
-
C++のフレンド関数とフレンドクラスの基本を解説
C++におけるフレンド関数(friend function)とは、クラスのスコープ外で定義される関数でありながら、そのクラスのすべてのprivateメンバーおよびprotectedメンバーにアクセスする権限を持つ特別な関数です。フレンド関数のプロトタイプ(宣言)はクラス定義の中に記述しますが、あくまで「友達」として扱われるだけであり、クラスのメンバー関数にはなりません。この点は重要なポイントです。フレンドとして指定できるものフレンドとして宣言できるのは、以下のようなものです。通常の関数関数テンプレート他のクラスのメンバー関数クラス全体(この場合、そのクラスのすべてのメンバーがフレンドになります