2016-12-13 5 views
0

私は1週間で答えが見つからないという問題があります。私は動的配列クラスを持っており、それに文字列値を追加するメソッドを持っています。アイテムを追加できる在庫を表すはずです。しかし、私は、main()の中でクラス要素 "backpack"の印刷メソッドを呼び出そうとしたときに、このメソッドで行われたclass要素のプライベート値に対する変更が "更新"されていないことがわかりました。これは問題を参照するために問題になるかもしれないと思いますが、クラスが別のモジュールに入っていないときにこの作業を見てきました。main()に変更を戻さないメソッドのクラスのプライベート値を変更する

私の「バックパック」モジュールのプリントとメソッドを追加:メイン

const int INITIAL_SIZE = 5; 
Inventory::Inventory(): 
     array_(new string[INITIAL_SIZE]), 
     max_space_(INITIAL_SIZE), 
     used_space_(0) {} 

void Inventory::add(string item){ 

if (size() == max_space_) { 
    string* new_array = new string[2 * max_space_]; 

    for (int i = 0; i < size(); ++i) { 
     new_array[i] = array_[i]; 
    } 

    delete [] array_; 

    array_ = new_array; 
    max_space_ = 2 * max_space_; 
} 

array_[used_space_] = item; 
++used_space_; 
} 

void Inventory::print() { 

for (int i = 0; i < size(); ++i) { 
    cout << array_[i] << endl; 
} 
} 

を():

Inventory inv; 
string input; 

while (cout << "input> " 
     and getline(cin,input)){ 

add_to_bag(input,inv); 

だから、ポイントは、あなたがそれを新しい内容を与えるとき、あなたは在庫をリセットしています。関数add_to_bag();あなたの問題がある

void add_to_bag(string input, Inventory inv){ 

    const string WHITESPACE1_REGEX = "[[:space:]]*"; 
    const string WHITESPACE2_REGEX = "[[:space:]]+"; 
    const string WORD_REGEX      = "[[:alpha:]_]+"; 

    const string LINE_REGEX = 
     WHITESPACE1_REGEX + 
     WORD_REGEX + 
     "(" + 
     WHITESPACE2_REGEX + 
     WORD_REGEX + 
     ")*" + 
     WHITESPACE1_REGEX; 

regex line_reg(LINE_REGEX); 
regex word_regex(WORD_REGEX); 

string line = input; 

    if (regex_match(line, line_reg)) { 

     sregex_iterator iter(line.begin(), line.end(), word_regex); 
     sregex_iterator end; 

     while (iter != end) { 
      inv.add(iter->str()); 
      ++iter; 
     } 

    } else { 

     cout << "Error: unknown inventory contents." << endl; 
    } 
} 
+2

メモリ管理をどのように扱うかを "学ぶ"必要がない限り、私はハンドベースの動的配列の代わりにデータを保持するために 'std :: vector'を使うことをお勧めします。 – crashmstr

答えて

6

:さ

void add_to_bag(string input, Inventory inv); 

あなたはadd_to_bagInventoryオブジェクトのコピーを渡します。あなたはそのコピーを修正します...そしてそれは捨て去ります。修正は、参照によって渡すことです:

void add_to_bag(string input, Inventory &inv); 

ところで、実際のコードでは、私は強くstd::vector<std::string>の使用を助言するのではなく、「独自のロール」。 Inventoryにデストラクタ(メモリリークを意味する)がないか、または正しいコピーコンストラクタを持っていない限り、私はあなたが "double free"を実行することを期待していました。ここで間違っているトリックな例外処理の問題がいくつかあります。問題。次のようにあなたのクラスは次のようになり設計する(。「三のルール」についての記事を読む)

0

簡単な方法:

class Inventory { 
private: 
    std::vector<std::string> items_; 

public: 
    Inventory(){} 
    ~Inventory(){} 

    void addItem(const std::string& item) { 
     items_.push_back(item); 
    } 

    void printInventory() const { 
     int idx = 0; 
     for (; idx < items_.size(); ++idx) { 
      std::cout << items_[idx] << std::endl; 
     }  
    } 

    void clearInventory() { 
     items_.clear(); 
    } 
}; 

とマーティンボナーはすでにの修正でそれに答えていた問題のためとして、それ以降のコピーと削除、およびメモリ管理に関するその他の問題が含まれます。

+0

はい、このようにするのが望ましいでしょうが、割り当てでは動的配列の使用のみが許可されます。 – murtourpo95

+0

@ murtourpo95 oh okay –

関連する問題