2017-03-20 6 views
2

私はC++を全く新しくしており、与えられたリットルパズルを解決するプログラムを書くことをお勧めします(3リットルと5リットルの容量を持つ2つの容器があります4リットルを取得するなど)関数はC++のオブジェクト属性を変更しません

私は、特定の容器のクラスと、ある容器の内容を別の容器に「流し込む」機能を書いています。ただし、クラス全体が公開されているにもかかわらず、このオブジェクトの内容の値は変更されません。私は何が間違っているのか分かりません。

#include <iostream> 
using namespace std; 

class Container { 
    public: 
     int quantity; //quantity of water in container 
     int size; //max amt of water 
}; 

void pour(Container a, Container b) { 

    int differential = b.size - b.quantity; 

    if (a.quantity <= differential) { 
     b.quantity = a.quantity + b.quantity; 
     a.quantity = 0; 
    } 

    else if (a.quantity > differential) { 
     b.quantity = b.quantity - differential; 
     a.quantity = a.quantity - differential; 
    } 

}; 

int main() { 
    Container bottle1; 
    bottle1.quantity = 5; 
    bottle1.size = 6; 

    Container bottle2; 
    bottle2.quantity = 0; 
    bottle2.size = 2; 

    pour(bottle2, bottle1); 


    cout << bottle1.quantity << ", " << bottle2.quantity << endl; 
    return 0; 
} 

私は私のミスが明らかであると確信しているが、私はどこにも答えを見つけることができません。

は、ここに私のコードです。どんな助けでも大歓迎です。

+2

引数を値ではなく参照で使用します。 'void pour(Container&a、Container&b)' – Jarod42

答えて

5

あなたはコピーとしてContainerを渡しています。つまり、pour関数で変更したコンテナは、関数の終了時に破棄されます。

void pour(Container& a, Container& b) 

&タイプが基準を示した後に:

溶液は、参照を使用することです。つまり、abのコピーをpourの内部で使用する代わりに、この関数は同じabに呼び出し元としてアクセスします。

3

これは、オブジェクトを値渡しするためです。あなたは参考にそれらを渡したいと思うでしょう。これを行うには、メソッドヘッダーを変更します。

本質的に、メソッドヘッダーのContainerの各インスタンスはContainer&になるはずです。コールを変更する必要はありません。

また、ポインタを渡すこともできます。あなたの議論はContainer *aになり、電話では各変数名の前にアンパサンド(&)を追加する必要があります(a&aになります)。また、オブジェクトの参照先を期間(.)から矢印(->)に変更する必要があります。

あなたの方法はなる:

void pour(Container *a, Container *b) { 

    int differential = b->size - b->quantity; 

    if (a->quantity <= differential) { 
     b->quantity = a->quantity + b->quantity; 
     a->quantity = 0; 
    } 

    else if (a->quantity > differential) { 
     b->quantity = b->quantity - differential; 
     a->quantity = a->quantity - differential; 
    } 

}; 

いくつかのケースでは、プログラムの設計者は、すべての参照がconstの参照である規則を採用しますので、私は両方を言及しました。つまり、参照渡しされたオブジェクトは変更されません(メソッドヘッダーの型名の前にconstキーワードを使用して強制されます)。その他のオブジェクトはすべてポインタによって渡されます。これにより、関数呼び出しで、引数が変更されるかどうかが明確になります。

この規約では、const参照を値渡しで使用することを選択すると、関数呼び出しの効率が向上します。オブジェクトのコピーを作成するよりも、参照を渡す方が早いです。

+1

あるいは、 'const'参照と非'const'参照を持つことができます。 – Charles

+0

真実ですが、一部の人々は、メソッド呼び出しからちょうど言うことができるようにしたいと訴える人もいます。ポインタを使用すると、メソッド呼び出しは基本的に変更を行うことを通知します。そうでなければ、メソッド呼び出しはメソッドが変更を行わないことを示唆しています。 –

+1

理にかなっていますが、それは何のドキュメントなのですか? – Charles