0
PhonebookEntry pb1("olaNormann");
pb1.add("Home","11234567");
pb1.add("Work","11065432");
cout << pb1.getNumbers()["Home"] << endl;
cout << pb1.getNumbers()["Work"] << endl;

map<string,string>::iterator it;
for(it = pb1.getNumbers().begin(); it != pb1.getNumbers().end(); ++it){
    cout << (*it).first << ": " << (*it).second << endl;
}

最初の 2 つの cout を使用して、2 つのペアが適切に追加されるようにしました。このコードは、Home と Work のラベルが付いた最初の 2 つの数値を出力しますが、for ループで両方の数値を出力できません。for ループは "Home: 11234567" のみを出力します。誰でも理由がわかりますか?以下は、関連するメソッドが実装された私のヘッダーファイルです。

class PhonebookEntry{
private:
    std::string name;
    std::map<std::string, std::string> numbers;
public:
    PhonebookEntry(std::string name) : name(name){}
    std::map<std::string, std::string> getNumbers() const {return numbers;}

    void add(const std::string label,const std::string number){numbers[label] = number;}
};
4

3 に答える 3

6

getNumbers()マップへの参照ではなく、マップのコピーを返しています。そのコピーは、関数呼び出しを含む式の最後で破棄されるため、ループ中は反復子が無効になり、それを使って何かを行うと、未定義の動作が発生します。

次のようになります。

map<string,string> & getNumbers();
                   ^

&参照を示します。オーバーロードを提供することも礼儀正しいでしょうconst:

map<string,string> const & getNumbers() const;
                   ^^^^^^^              ^^^^^

この変更により、コードは期待どおりに動作するはずです。デモンストレーションを参照してください

于 2012-04-18T15:35:20.933 に答える
2

これがあなたの方法である場合:

std::map<std::string, std::string> getNumbers() const {return numbers;} 

numbers次に、マップのコピーを返します。したがって、ループでは、イテレータはすべて混乱しています。

for(it = pb1.getNumbers().begin(); it != pb1.getNumbers().end(); ++it) { ... }

まず、マップの1つのコピーで初期化されます。次に、別のコピーの終了イテレータと比較されます。参照により地図を返却する必要があります。

const std::map<std::string, std::string>& getNumbers() const {return numbers;} 
于 2012-04-18T15:36:37.690 に答える
0

ここでは、2 つの個別の問題が発生しています。

  1. テンポラリーに値を挿入して出力する
  2. 破棄後の一時的なイテレータの使用

問題1

cout << pb1.getNumbers()["Home"] << endl;

が呼び出されたときにまだ有効な return のため、出力が表示されstd::map<T,U>::operator[]ます。ただし、テンポラリは式の最後で破棄されます。U&operator<<(std::cout, U&)

問題 2

for(it = pb1.getNumbers().begin(); it != pb1.getNumbers().end(); ++it) { ... }

getNumbers()マイクが彼の答えでよく説明しているように、によって返される一時はループ本体では無効です。

于 2012-04-18T15:49:32.037 に答える