0

データの扱い方をいろいろいじっていたところ、以下のよくわからない挙動に出くわしました。firstDoubleIter以下のコードを読む際には、変数とに注意してくださいsecondDoubleIter。特に、変数が指しているリスト (さまざまなコピー) の要素に注意してください。

私の質問は以下です。

#include <list>                                                                      
#include <iostream>                                                                  

template <class T>                                                                                            
class MyListContainer                                                                
{                                                                                    
  public:                                                                            
    std::list<T> list;                                                               
    MyListContainer() : list() {;}                                                   
    MyListContainer(const MyListContainer& container) : list(container.list) {;}     
    MyListContainer(std::list<T> list) : list(list) {;}                              
    std::list<T> getList() const {return list;}                                      
};                                                                                   

int main()                                                                           
{                                                                                    
  typedef MyListContainer<double> DoubleList;                                        
  DoubleList doubleContainer = DoubleList(std::list<double>({0, 1}));                
  auto firstDoubleIter = doubleContainer.getList().begin();                          
  auto secondDoubleIter = ++(doubleContainer.getList().begin());                     
  std::cout << "Using the getList() method\n";                                       
  std::cout << "*firstDoubleIter = " << *firstDoubleIter << "\n";                    
  std::cout << "*secondDoubleIter = " << *secondDoubleIter << "\n";                  

  std::list<double> listOfDoubles = doubleContainer.list;                            
  firstDoubleIter = listOfDoubles.begin();                                           
  secondDoubleIter = ++listOfDoubles.begin();                                        
  std::cout << "Accessing the list directly\n";                                      
  std::cout << "*firstDoubleIter = " << *firstDoubleIter << "\n";                    
  std::cout << "*secondDoubleIter = " << *secondDoubleIter << "\n";                  
}

次の出力が生成されます。

Using the getList() method
*firstDoubleIter = 1
*secondDoubleIter = 0
Accessing the list directly
*firstDoubleIter = 0
*secondDoubleIter = 1

私の理解では、 と の値は、暗黙的なリストのコピーでも同じでなければなりません*firstDoubleIter*secondDoubleIter

私の質問は: なぜそれらは同じではないのですか?

4

1 に答える 1

4

最初のケースでは、 を呼び出すたびgetListにリストの一時コピーが返され、ステートメントの最後で破棄されます。イテレータは有効なリスト要素を参照しなくなったため、それらを逆参照すると未定義の動作が発生します。

2 番目のケースでは、リストのローカル コピーを保存するため、反復子は引き続き有効です。

このクラスをどのように使用するかによって、おそらくgetListコピーではなく参照を返したいと思うでしょう。

于 2013-11-12T08:34:50.687 に答える