0

こんにちは、C++ 仮想関数に関して 1 つの質問があります...

class base{
 public :
    base()  { a=5;}
    int a;
    virtual void print()=0;
    int get(){return a;}
    int get_var(){ a=5;  return a;}
};  

int main(void){
    base *p;
    cout <<"Get Call - No assign\n";
    cout <<"Value is :: "<<p->get()<<endl;
    cout <<"Get Call - assign value\n";
    cout <<"Value is :: "<<p->get_var()<<endl;
    return 0;
}

その o/p は :: Get Call - No assign Value is :: 5 セグメンテーション違反

私はこの動作を理解していませんか?
私が考えることができる理由の1つは、ベースが抽象クラスであるため、つまり完全な実装がないため、a = 5を実行しているときにクラッシュすることです。
しかし、最初の呼び出しでも私はを使用しているので、そこでクラッシュしないのはなぜですか
助けてください....

4

4 に答える 4

3

根本的な原因:

ポインターpは有効なオブジェクトを指していないため、メンバー関数を呼び出して逆参照すると クラッシュします (実際にはUndefined Behaviorです)。

ポインターが任意のランダム アドレスを指すだけであることを宣言する場合は、ポインターを使用して意味のあることを実行できるように、有効なオブジェクトを指すようにする必要があります。

解決:

必要なもの:

base *p = new base; 

また

base obj;
base *p = &obj;

上記のいずれかが機能するにbaseは、非抽象クラスである必要があります。あなたの例baseは抽象クラス(少なくとも1つの純粋仮想関数を持つクラス)です。そのようなクラスの場合、そのオブジェクトを作成することはできません(そのコンストラクターを呼び出します) )。
したがって、この問題を解決するには、抽象クラスから派生する派生クラスを作成し、派生クラスbaseの純粋仮想関数print()を実装して、派生クラスを抽象クラスではなく具象クラスにする必要があります。次に、職場での動的ディスパッチを確認できます(それがあなたの目的だったと思います

class Derived:public base
{
    public:
        virtual void print()
        {
            //Do some prints
        }
};

int main()
{
    Derived obj;
    Base *ptr = &obj;

    //or

    Base *ptr2 = new Derived;

    //.....Rest of your program as is
}
于 2012-08-28T12:35:47.767 に答える
2

を初期化していないbase *p;ため、メソッドを呼び出すことは未定義の動作です(あなたの場合はセグメンテーション違反)。

base反対に、抽象クラスであるため、初期化することはできません。printinbaseまたは in a 派生クラスの定義を提供する必要があります。

于 2012-08-28T12:36:25.787 に答える
1

私が考えることができる理由の1つは、ベースが抽象クラスであるため、つまり完全な実装がないため、a = 5を実行しているときにクラッシュすることです。

いいえ、クラッシュは、初期化されたポインターを逆参照することによって発生しますp(技術的に未定義の動作)。抽象的であるためbase、インスタンスを作成する方法はありません。

base b;             // Illegal
base* p = new base; // Illegal 

投稿されたコードには、派生した具象クラスはありません。base純粋仮想関数から派生して実装する必要がありますprint()。クラスのデストラクタbasevirtual.

于 2012-08-28T12:38:18.413 に答える
0

p初期化されていないポインタです。したがって、それでほとんど何でもすることは、未定義の動作です。

そして、「なぜ以前にクラッシュしなかったのか」に対する答えは、たいてい「運」です (良いか悪いかは、見方によって異なります)。動作が未定義のプログラムは、動作しているように見えたり、クラッシュしたり、マウスが爆発したりするなど、あらゆることを行うことができます。

于 2012-08-28T12:38:26.587 に答える