2016-12-09 8 views
0

この短いコードでセグメンテーションフォルトが発生しており、その理由を特定できません。派生クラスで仮想関数を呼び出すときにセグメンテーションフォールトを取得する

taking address of temporary [-fpermissive] 

おかげで:

class XorY { 
public: 
    virtual void set_cost(double& cost){} 

}; 
class X_based:public XorY { 
public: 
    X_based(int _x):x(_x){} 
    void set_cost(double& cost) 
    { 
     cost=cost*(100-x)/100; 
    } 
    int x; 
}; 
class Y_based:public XorY 
{  
    public: 
     Y_based(){} 
     Y_based(int _y): y(_y){} 
     void set_cost(double& cost){ 
      cost=cost-y; 
     } 
     int y; 
}; 


int main(){ 
    double a=2; 
    XorY* type; 
    Y_based* ptr; 
    *ptr=Y_based(3); 
    type=ptr; 
    type->set_cost(a); 
} 

私が私がこのコンパイルエラーを取得

ptr=&Y_based(3); 

にそれを変更するには、このライン

*ptr=Y_based(3); 

との誤差がありますようです前進。

+3

ヒント:これを行うとき、 'ptr'は何を指していますか? '* ptr = Y_based(3);'。 – juanchopanza

+0

私はY_basedクラスのオブジェクトを指し示すようにしようとしています。それを行うコンストラクタを呼び出しています。 –

+2

@ Ghazal.S、初期化されていないポインタを逆参照する、または有効なオブジェクトを指すように設定されていると、動作。あなたの場合、 'ptr'はそのようなポインタです。 –

答えて

1

そうだね、ライン

*ptr=Y_based(3); 

が正しくありません。私は、ptrポインターが、この操作の後にタイプY_basedの新しいオブジェクトを指す必要があることを意味しています。

ホヴェール、この行の意味は異なります。

まず、右側部分(Y_based(3))が計算されます。これはタイプY_basedのオブジェクトで、_yフィールドは3に等しい。その後、左部分(*ptr)が計算されます。 ptrポインターが指し示すオブジェクトであり、ポインターが初期化されていないため定義されていません。ポインタが初期化されている場合は、その後、右部分の値が左部分の値に割り当てられます。つまり、ポインタ自体ではなく、ptrが指すオブジェクトが変更されます。

あなたの望ましい行動がここに割り当てられている左部分を、

ptr = new Y_based(3); 

を書き込むことによって達成することができ、それによりptr指すオブジェクトが、ptr自体、及び右部分がへのポインタではありません新しく作成されたタイプY_basedのオブジェクトです。タイプY_basedのオブジェクトがnewキーワードによって作成されたので、あなたがブロックを離れた後

はまた、それが破壊されることはありません、あなたはあなたが必要のないラインでdeleteを使用して、手動でそれの世話をする必要がありますもうオブジェクト。あなたがすべてのこのようなものを気にしたいのですが、まだ持っている必要がない場合は

class XorY { 
public: 
    virtual void set_cost(double& cost){} 
    virtual ~XorY() = default; 
}; 

:正しく基底クラスへのポインタでオブジェクトを破壊するために、あなたはまた、基本クラスで仮想デストラクタを定義する必要があります多態的な振る舞いでは、ポインタの代わりに参照を使うことができます:

int main(){ 
    double a=2; 
    Y_based& ptr = Y_based(3); 
    XorY& type = ptr; 
    type.set_cost(a); 
} 
+0

ええ、今私はそれを得る。たくさんのありがとう:) @ alexeykuzmin0 –

関連する問題