2009-06-25 20 views
3

私は*これは良い考えですか?

return *this 

は、我々はメンバ関数を呼び出したクラスのインスタンスを返すことができる唯一の方法であるかどうかわからないんだけど?私が尋ねた理由は、インストラクターが必要に応じてポインタを使用しないように指示していたため、これを行う必要があるのはこのポインタを返すだけなのかなと思います。

私は、プライベートデータメンバーの分子と分母を保持する分数クラスを扱っています。私が話しているメンバ関数は、例えば二つの画分を追加するために使用されます。講師は私たちがC = A + =をやりたい

Fraction& plus(const Fraction frac) 

Fraction C = A.plus(B); 

プラスメンバー関数は、このように定義されますBなので、それが理由だと思います。

+13

新しいインストラクターを取得してください。 –

+1

プラスはあなたの例でAを修正するはずですか?そうでない場合は、AとBの合計である新しいFractionオブジェクトを返す必要があります。 –

答えて

7

新しいインストラクターを取得してください。 plus()の宣言が完全に間違っているかのように見えます。

  • それはおそらく、それは間違いなく、パラメータ
としてconst参照を取る必要があり、それは参照を返す必要がある場合、それはconst参照
  • を返すべき値ではなく参照
  • を返す必要があります

    これは、メンバーplus()関数の分かりやすい実装のためのものです。もちろん、それはおそらく友人だろう。

  • +0

    あなたは最初の点で私の心を読んでいます:D – AraK

    +0

    これは悪い生徒が間違った質問を間違ってコピーしている可能性が高いと思います。私は、ポインタへの参照を好むと主張するだろう。そして、教師が再テストしたときのポインタではなく、参照が返されます。 –

    +0

    'plus'が' operator + = 'に対応すると仮定し、値渡しが参照渡しよりも速くなることを期待するなら、宣言は問題ありません。 (私がそれがここに当てはまるなら、私は驚かないだろう) –

    1

    はい、これが唯一の方法です。メソッド内の現在のオブジェクトにアクセスする唯一の方法は、これを経由して、ポインタです。

    これは問題なく、受け入れられています。

    1

    *thisを返すことは何も問題ありません。例えば、これは修正演算子のオーバーロードがどのように働くことになっているかです。 +メソッドは実際に演算子をオーバーロードしないであなたのクラスに演算子+ =を与える単なる方法であると思われます(私はあなたが演算子のオーバーロードに慣れていないと仮定します)ので、この場合は*thisを返すのが通常の動作です。

    0

    plus()メソッドでは、現在のオブジェクトを変更して*thisを返す代わりに、新しいFractionオブジェクトを作成して返してください。 にAを変更したくない可能性があります。新しいFractionを返すには、plus()の署名が最善のようになります。

    Fraction plus(const Fraction &frac); 
    

    (現在plus()方法でthisを変更していない場合は、なぜあなたは*thisを返すようにしたいですか?)

    2

    Iそれが存在することが保証されているので、thisは、現在のオブジェクトを参照するので、それがnullではありませんので、

    return *this 
    

    を使用しても安全であるこのケースで考えます。上記ケースCに加算の結果をコピーすることによって作成されること

    Fraction C = A.plus(B).plus(D) // perhaps? 
    

    plus戻る自体への参照理由は、それが連鎖することができるようになります。 これは、操作plusがオブジェクト(この場合はA)を変更し、この変更されたオブジェクトへの参照を返すことを前提としています。

    パラメータのコピーを作成する代わりに参照を受け入れることはできませんか?

    Fraction& plus(const Fraction& frac) 
    

    これは、あなたがoperator=(例)を実装する方法を次のようになります

    A& operator=(const A& right) { 
        if(this == &right) return *this; // Handle self-assignment 
        b = right.b; 
        return *this; 
        } 
    

    たぶん、あなたがオブジェクトを変更し、新しいオブジェクトを返さないしたい:

    // assuming there's a constructor Fraction(int numerator, int denominator): 
    Fraction* plus(Fraction const& rhs) 
    { 
        return new Fraction(numerator * rhs.denominator 
             + rhs.numerator * denominator, 
             denominator * rhs.denominator); 
    } 
    

    しかし、このもちろんあなたのタスク(?)で必要とされるかもしれないリファレンスではない新しいインスタンスへのポインタを返さなければなりません。

    あるいはさらに良い:

    Fraction plus(Fraction const& rhs) 
    { 
        return Fraction(numerator * rhs.denominator 
            + rhs.numerator * denominator, 
            denominator * rhs.denominator); 
    } 
    

    これはリターンに構造をコピーするオーバーヘッドがありませんので、関数を呼び出すの空間に分数を作成します。

    +0

    実際、これはnull以外であることは保証されていません。 NULLオブジェクトのメソッドを呼び出すと、逆参照されるとクラッシュすることになります。 – Michael

    +0

    しかしその場合は、あなたが返すことを試みるときプラスではなくNULLをプラスしようとするとクラッシュする*これは私が仮定する – stefanB

    +0

    関数が仮想であればクラッシュするだろう。 vtable。それ以外の場合は、無効なパラメータを持つ非メンバ関数を呼び出すようなものです。 – Michael

    0

    私は、セマンティクスは、メンバー関数 'plus'が呼び出し側と呼び出し側の合計を表す 'new'オブジェクトを返すということであると考えています。 ノート::新しいあなたが側面を持っている演算子をオーバーロードするとき、私はこれへの参照を返すために、それが正しい見唯一の場所である、あなたの例のためにそう

    // the constructor accepts (numerator, denominator). 
    // in your case, the caller object would be A, and the called object would be B(other). 
    return Fraction(numerator * other.denominator + other.numerator * denominator, denominator * other.denominator); 
    

    をC++での「新しい」キーワード:) を意味するものではありません効果。

    以上を明確にするために、これはあなたの「プラス」署名する必要があり、呼び出し側にも呼ば

    Fraction plus(const Fraction& frac); 
    

    どちらも「プラス」によってもたらされなければなりません。

    0

    あなたが実際にポインタではなく、ポインタを逆参照の値を返している

    必要であれば、私たちのインストラクターは、ポインタを使用しないように私たちに語りました。だから、あなたはすばらしいはずです。

    個人的には、私は決して明示的にメソッドを呼び出したり、thisでメンバーを参照したりしません。それは私が次の操作を実行しないでください、次のとおりです。

    class A { 
        public: 
        int x; 
        int get_x() 
        { 
         return this->x; 
        } 
    
        int get_x_plus_5() 
        { 
         return this->get_x() + 5; 
        } 
    } 
    

    しかし、私は*thisを返すと完全に元気です。

    あなたのインストラクターは、(1)関数からスタック上のオブジェクトへのポインタを返すことを避けるようにしようとしています(つまり、関数が終了しても存在しないことを意味します)あなたがする必要がないとき。 thisには、これらの問題のいずれかが発生しません。