1

アップキャストについて疑問があります。Class Parent と Class child という 2 つのクラスがあるとします。子は親から継承されました。

質問:

親のオブジェクト ポインターを作成し、子オブジェクト参照を割り当てた場合。遵守しました。出力は「オブジェクトのスライス」です。子クラス固有のコンポーネントにアクセスできませんでした

class Parent
{
public:
    int i;

    void school()
    {
        std::cout<<"Parent Class::School()"<<std::endl;
    }
    // virtual goToPlay()
    // {
    //       std::cout<<"Parent Class::goToPlay()"<<std::endl;
    // }    

 };

class Child:public Parent
{
public:
    int j;
    void goToPlay()
    {
        std::cout<<"Child Class::goToPlay()"<<std::endl;
    }
};

int main()
{
    Parent *mParent;
    Child mChild;
    mParent = &mChild;

    mParent->school();
    mParent->goToPlay(); //Error

goToPlay() API にアクセスできませんでした。親クラスで goToPlay() の仮想関数を作成すると、アクセス可能になります。誰でもその理由を教えてもらえますか?

4

3 に答える 3

1

を明示的に宣言するParent * mParentので、オブジェクトは のインスタンスとして扱われますParent。多くのユースケースでは、これはまさにあなたが望むものです - 何かを行うための適切なインターフェースを提供し、具体的に使用される実装はエンドユーザーには関係ありません:

class employee
{
    public:
        virtual double get_salary_in_usd() const = 0;
        virtual ~employee() {}
};

class software_developer : public employee
{
    public:
        double get_salary_in_usd() const { return 100000.; /* i wish */ }
        void be_awesome() {}
        ~software_developer() {}
};

void print_salary(std::shared_ptr<employee> const & emp)
{
    std::cout << "This employee earns $" << emp->get_salary_in_usd()
              << " a month." << '\n';
}

ただし、場合によっては、ポインターが基本クラスの特定の子であるかどうかを実行時に通知する必要があります。これがdynamic_cast目的です:

software_developer me;
employee * me_generalized = &me;

software_developer * me_again = dynamic_cast<software_developer *>(
    me_generalized);
if(me_again != nullptr)
{
    me_again->be_awesome();
}

ポインターをキャストできなかった場合にdynamic_cast返される可能性があることに注意してください。nullptrまた、これは実行時に RTTI で発生し、アプリケーションの速度が低下することにも注意してください。可能な限り、これを使用しないでください。

于 2013-08-06T07:51:32.353 に答える