解除引用STL集的迭代器

时间:2013-06-22 15:16:55

标签: c++ inheritance stl set dereference

我遇到了从STL集继承的问题(我认为):

这是Prime类:

class Prime : public set<A> {
private:
  // private data members.
public:
  // C'tor...
  void printParticularA(const int& id);
}

这是A类:

class A : public List<B>{  
private:  
  // data members.  
  int id;
public:  
  // C'tor  
  A(const A& copy) : List<B>(copy), //copy data members  
     { // validate data and throw exceptions if needed. };

  bool operator< (const A& rhs) const{  
    return id < rhs.id;  
  }

  void printReport() const {  
    for(const B& item : *this){ item.print(); }
  }

}

现在这是问题所在。在下一个函数中,我想在集合中打印特定的A对象:

void Prime::printParticularA(const int& id) {
  find(AFinder(id))->printReport();
}

我也尝试过这个:

void Prime::printParticularA(const int& id) {
  *(find(AFinder(id))).printReport();
}

注意:假设B类有print()方法 注2:AFinder是一个仅使用id数据制作虚拟A对象的类。

问题是当'find'找到对象时它返回const_iterator(因为set中的每个对象都是const),当我取消引用它时,我得到一个对象的副本(??)但是它里面的B列表是空的!
这也适用于' - &gt;'版本

现在我知道set不允许我更改对象,但我不打算更改对象(正如您在printReport成员函数声明中看到的那样)。

我感谢任何帮助!

编辑:谢谢大家,你们帮助了我很多,尤其是学习不该做的事情 我解决了这个问题,它不是在集合,列表中,也不是我在这里提出的任何课程 我的错误在于理解我给出的问题(是的,这是我的家庭作业,我还是c ++的新手)。
抱歉,如果你觉得我浪费了你的时间 我希望我能从你的所有经验中学习,有一天能帮助别人! 总之,谢谢!! :)

3 个答案:

答案 0 :(得分:1)

你的代码几乎搞砸了。并且问题看起来并不直接与set或iterator绑定,而是一般的坏事。

对于初学者来说,你的op&lt; const并删除副本ctor为好 - 股票应该工作正常。使用set的内部查找来搜索并查看是否找到了项目。

所有这些都可能会使您描述的问题消失,如果没有,请发布一个完整的可编译示例,其中包含您所看到的内容和您期望的正确文本。

答案 1 :(得分:1)

虽然您没有包含List的实施,但可能存在问题。更准确地说,begin()的{​​{1}}和end()成员函数可能会被破坏。机会是它们返回的值相同(或无效),导致基于循环的范围无效。这当然是基于你的List返回一个有效的迭代器而不是 end 迭代器。

以下示例是对问题中代码的修改。它使用set::find代替std::list而不使用List,因为您没有为其添加代码。

AFinder

这会产生以下输出。

  找到1个   B :: id = 1
  B :: id = 2
  B :: id = 3
  完成找到1
  找到2
  B :: id = 4
  B :: id = 5
  B :: id = 6
  完成找到2
  找到3
  没找到
  完成了发现3

答案 2 :(得分:1)

您的代码确实违反了许多C ++规则。你为什么不试试像这样的人:

#include <iostream>
#include <list>
#include <map>

using namespace std;

class SimpleInt {
public:  
  int data_;

  SimpleInt(const int data): data_(data) {};
  void print() const {cout << data_ << " ";};
};

template <typename T>
class A {  
private:  
  // private data members.  
public:  
  list<T> list_of_B_; // this is for simlicity. Make getters as you need
  const int id_; // delete it or copy to map. You sholdn't change it.

  A(int id) : list_of_B_(), id_(id) {} 
  A(const A<T>& copy) : list_of_B_(copy.list_of_B_), id_(copy.id_) {} //copy data members  
  A(A<T>&& copy) : list_of_B_(::std::move(copy.list_of_B_)), id_(copy.id_) {} //move data members  

  void printReport() const {  
    for(const T& item : list_of_B_){ item.print(); }
  }

};

template <typename T>
class Prime {
private:
  // private data members.
public:
  // The main difference with your source
  map<int, T> map_of_A_; // this is for simlicity. Make getters as you need
  // C'tor...
  void printParticularA(const int& id) {
    auto it = map_of_A_.find(id);
    if (it != map_of_A_.end())
      it->second.printReport();
  }
};

int _tmain(int argc, _TCHAR* argv[])
{
  typedef A<SimpleInt> ASimpled;
  Prime<ASimpled> prime;
  ASimpled a(1);
  a.list_of_B_.push_back(SimleInt(1));
  a.list_of_B_.push_back(SimleInt(2));
  a.list_of_B_.push_back(SimleInt(3));
  ASimpled b(2);
  b.list_of_B_.push_back(SimleInt(10));
  b.list_of_B_.push_back(SimleInt(20));
  b.list_of_B_.push_back(SimleInt(30));
  prime.map_of_A_.insert(make_pair(a.id_, a));
  prime.map_of_A_.insert(make_pair(b.id_, b));

  prime.printParticularA(2);

return 0;
}