次の方法で共有


キャスト

C++ では、1 つ以上の仮想関数を含む基底クラスからクラスが派生している場合、その基底クラス型へのポインターを使用して、派生クラス オブジェクト内の仮想関数を呼び出せます。 仮想関数を含むクラスは、"ポリモーフィックなクラス" と呼ばれます。

C が B から派生し、これが A から派生するクラス階層の図。
クラスの階層構造

C 型のオブジェクトは、次のように視覚化できます。

サブオブジェクト B とサブオブジェクト A を含むクラス C の図。
サブオブジェクト B とサブオブジェクト A を持つクラス C

C クラスのインスタンスに、B サブオブジェクトと A サブオブジェクトがあります。 C サブオブジェクトと A サブオブジェクトを含む B のインスタンスは、「完全なオブジェクト」です。

派生クラスには、派生元のすべての基底クラスの定義が完全に含まれるため、ポインターを任意の基底クラス (アップキャストとも呼ばれます) にキャストするのは安全です。 基底クラスへのポインターを指定すると、派生クラス (ダウンキャストとも呼ばれます) のインスタンスにポインターをキャストするのは安全である場合があります。

実行時の型情報を使用すると、ポインターが実際に完全なオブジェクトをポイントしていて、階層内の別のオブジェクトをポイントするように安全にキャストできるかどうかを調べることができます。 dynamic_cast 演算子は、操作が安全であることを保証するために、実行時チェックを実行します。 クラス階層は、仮想関数を使用して、ダウンキャストの必要を回避できるように設計することをお勧めします。 ただし、ダウンキャストする必要がある場合は、操作が安全であることを確認するために、dynamic_cast を使用します。

非ポリモーフィックな型の変換については、static_cast 演算子を使用できます (このトピックでは、静的および動的なキャスト変換の違いと、それぞれの使用に適した場合について説明します)。

次の例は、dynamic_caststatic_cast の使い方を示しています。

#include <iostream>

class Base {
public:
    virtual void print() { std::cout << "Base\n"; }
};

class Derived1 : public Base {
public:
    void print() override { std::cout << "Derived1\n"; }
};

class Derived2 : public Base {
public:
    void print() override { std::cout << "Derived2\n"; }
};

class MostDerived : public Derived1, public Derived2 {
public:
    void print() override { std::cout << "MostDerived\n"; }
};

int main() {
    MostDerived md;
    Base* b1 = static_cast<Derived1*>(&md); // Upcast to Derived1 is safe
    Base* b2 = static_cast<Derived2*>(&md); // Upcast to Derived2 is safe

    // Downcast to MostDerived is ambiguous and unsafe
    // MostDerived* md1 = static_cast<MostDerived*>(b1); // This won't compile
    // MostDerived* md2 = static_cast<MostDerived*>(b2); // This won't compile

    // Correct way to downcast in this situation
    MostDerived* md1 = dynamic_cast<MostDerived*>(b1); // This is safe
    MostDerived* md2 = dynamic_cast<MostDerived*>(b2); // This is safe

    md1->print(); // Prints "MostDerived"
    md2->print(); // Prints "MostDerived"

    return 0;
}

このセクションは、次のトピックで構成されています。

関連項目