0

興味深いエラーが発生しました。これは、条件ステートメントのコンテキストでの包含ポリモーフィズムに関係していると確信しています。

この例のハイライトは次のとおりです。

   ClassParent *parentPointer; //Declare pointer to parent

   if(condition){
       ClassChild1   = mychild; //Declare child1 object
       parentPointer = *mychild;//Parent pointer points to child
   }

   if(!condition){
       ClassChild2   = mychild; //Declare child2
       parentPointer = *mychild;//Parent pointer points to child2  
   }

   cout << *parentPointer; //What will this point to???

明らかなように、条件文は最後の行で *parentPointer 変数を作成します。

私の関数全体は次のようになります:(クラッシュした場所に注意してください)

    void PosApp::addItem(bool isPerishable) {
        Item *refitem;

        if (isPerishable) {
            Perishable myitem;
            std::cout   << "Enter the following: "  << std::endl
                        << "Sku: "                  << std::endl
                        << "Name:"                  << std::endl
                        << "Price: "                << std::endl
                        << "Taxed: "                << std::endl
                        << "Quantity: "             << std::endl
                        << "Expiry date: "          << std::endl;

            std::cin    >> myitem;
            refitem = &myitem; //Item now implements inclusion polymorphism,  be aware of dynamic/static types (dynamic is item, static Perishable)
        }

        if (!isPerishable) {
            NonPerishable myitem;
            std::cout   << "Enter the following: "  << std::endl
                        << "Sku: "                  << std::endl
                        << "Name:"                  << std::endl
                        << "Price: "                << std::endl
                        << "Taxed: "                << std::endl
                        << "Quantity: "             << std::endl;

            std::cin    >> myitem;
            refitem = &myitem; //Item now implements inclusion polymorphism,  be aware of dynamic/static types (dynamic is item, static NonPerishable)


        }

        if (cin.fail()) {//The inclusion polymorphism allows me to call this block only once regardless of persh/non-perishable
            cin.clear();
            cin.ignore(2000, '\n');

            //CRASH POINT***********
            cout << "Error: " << *refitem << endl;//Be aware of early/late binding, the write/dowrite must be child calls, not parent.
        }


    }

ここで非常に興味深いのは、cin.fail の if() を削除し、入力でエラーを強制すると、機能することです。コードは次のようになります。

    void PosApp::addItem(bool isPerishable) {
        Item *refitem;


        if (!isPerishable) {
            NonPerishable myitem;
            std::cout   << "Enter the following: "  << std::endl
                        << "Sku: "                  << std::endl
                        << "Name:"                  << std::endl
                        << "Price: "                << std::endl
                        << "Taxed: "                << std::endl
                        << "Quantity: "             << std::endl;

            std::cin    >> myitem;
            refitem = &myitem; //Item now implements inclusion polymorphism,  be aware of dynamic/static types (dynamic is item, static NonPerishable)


            cin.clear();
            cin.ignore(2000, '\n');

            //THIS DOES NOT CRASH NOW
            cout << "Error: " << *refitem << endl;//Be aware of early/late binding, the write/dowrite must be child calls, not parent.



    }

クラッシュに関して私が思いついた最良の答えは、最初のコード スニペットでスコープが解決されたときに、プログラムがポインターの内容を失ったということです。

この質問には 2 つの要素があります: 条件付きのコンテキストで包含ポリモーフィズムを (示されているように) 実装できますか? そうでない場合、これが私のプログラムのクラッシュの原因ですか?

注: プログラム全体は含めませんでしたが (数百行に及ぶため)、コードを 2 番目のスニペットに変更したときの動作は期待どおりであると言えます。

4

1 に答える 1

5

自動ストレージを持つオブジェクトは、ステートメント{ }を含め、それらを囲む中括弧に対してローカルです。ifローカルへのポインターがあり、オブジェクトがスコープ外になった場合、そのポインターへのアクセスは UB です。

Object* ptr;
if (condition)
{
    Object obj;
    ptr = &obj;
} //obj is out of scope
*ptr; //undefined behaviour

これはrefitem、ローカル オブジェクトを指すように設定して行っていることです。代わりに、Perishable*またはNonPerishable*を使用して作成しnew、ブロックが終了したら、そのポインタを に割り当てますrefitem。ポリモーフィズムは期待どおりに機能します。エラーはオブジェクトのスコープだけでした。

if (!isPerishable)
{
    NonPerishable* myitem = new NonPerishable(); //dynamic memory
    std::cin >> *myitem;
    refitem = myitem; //refitem is still valid after this scope ends
}
于 2015-12-05T04:37:14.070 に答える