通过getter访问列表元素与直接访问类成员可以得到不同的答案

时间:2013-11-12 08:29:23

标签: c++

当我遇到以下我不理解的行为时,我正在摆弄各种处理数据的方法。在阅读下面的代码时,请注意变量firstDoubleItersecondDoubleIter,特别是它们所指向的列表(各种副本)的哪些元素。

我的问题如下。

#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的值也应该相同。

我的问题是:为什么他们不一样?

1 个答案:

答案 0 :(得分:4)

在第一种情况下,每次调用getList都会返回列表的临时副本,并在语句结束时销毁。由于迭代器不再引用有效的列表元素,因此在取消引用它们时会出现未定义的行为。

在第二种情况下,您存储列表的本地副本,因此迭代器仍然有效。

根据您打算如何使用此类,您可能希望getList返回引用而不是副本。