【问题标题】:How to access class data in a set of pointers to that class如何访问指向该类的一组指针中的类数据
【发布时间】:2015-06-11 13:48:49
【问题描述】:

我有一组指针:

set<StudentInterface*, Comparator> studentSet;

这些指针指向 Student 类,这些类继承自 StudentInterface 并包含一个 int 值 ID。我想测试某个类是否具有特定的 ID 值。我目前这样做的想法如下:

if(studentSet.find(????->getID()) != studentSet.end()) /* do something */

有没有办法以这种方式访问​​数据元素?如果不是,我可以访问这些元素以测试它们的最短方式(在代码行中)是什么?

【问题讨论】:

  • 一定要用套吗?使用地图可以轻松执行此操作。
  • 我知道是的。我必须使用一套,因为它是家庭作业的一部分。我说IDint,但实际上是unsigned long long int,因为他们想让我们的生活变得困难。

标签: c++ set


【解决方案1】:

我认为您不能使用任何 STL 容器(如 vector/set/map)中的 find 函数来搜索类的特定元素值。

您可以通过以下方式执行此操作:

for ( auto x : studentSet )
{
    if ( x->getID() == ???? )
    {
        /* Do something */
    }
}

或者,如果您可以制作一个要搜索的对象,那么您可以按照您的问题做同样的事情:

if ( studentSet.find(studentSet.begin(), studentSet.end(), YourObject) != studentSet.end() )
    /* do something */

【讨论】:

  • auto 是否只是假设您正在寻找定义该集合的数据类型? (就像在我的情况下一样StudentInterface*?)
  • 只要您使用标志 -std=c++11,它就可以。如果您不打算更改集合/向量/数组中的任何值,我建议您这样做const auto &amp;
  • T // 我正在复制这个 T&amp; // 我正在修改这个 const T&amp; // 我正在阅读这个 如果你只搜索它而不修改它,那么 @ 987654329@会提高效率
【解决方案2】:

好的,我对这个问题有一个初步的答案。我可以使用以下内容在集合中搜索所需元素:

for(StudentInterface* currentSetElement : studentSet) if(currentSetElement->getID() == ID) /* do something */

不确定这是否是最好的方法,但我认为它有效。

【讨论】:

    【解决方案3】:

    您还可以使用库中包含的set 的迭代器。例如,给定集合studentSet,您可以:

    for (std::set<StudentInterface*, Comparator>::iterator it=studentSet.begin(); it!=studentSet.end(); ++it){
    //Code here, example:
        *it->getID();
    }
    

    这个for 将从studentSet 的第一个元素迭代到最后一个元素,it 接收存储的对象。此外,it 将接收到该元素的引用(指针)。

    【讨论】:

      【解决方案4】:

      时间用完了。使用集合然后手动搜索集合是没有意义的。还不如使用向量。 下面是一个更好的框架:

      #include <iostream>
      #include <set>
      
      using namespace std;
      
      class Interface
      {
      public:
          Interface(int ID):mID(ID)
          {
      
          }
          bool operator<(const Interface& rhs)
          {
              return mID < rhs.mID;
          }
      
          int mID;
      };
      
      class InterfaceTest:public Interface
      {
      public:
          InterfaceTest(int ID): Interface(ID)
          {
      
          }
      };
      
      class InterfaceKey:public Interface
      {
      public:
          InterfaceKey(int ID): Interface(ID)
          {
      
          }
      };
      
      
      struct compare {
          bool operator() ( Interface* const& lhs, Interface* const& rhs) const{
              return *lhs < *rhs;
          }
      };
      int main()
      {
          set<Interface*, compare> testset;
      
          testset.insert(new InterfaceTest(1));
          testset.insert(new InterfaceTest(2));
          testset.insert(new InterfaceTest(3));
          testset.insert(new InterfaceTest(4));
      
          InterfaceKey A(1);
          if (testset.find(&A) != testset.end())
          {
              cout << "Found A" << endl;
          }
          InterfaceKey B(5);
          if (testset.find(&B) == testset.end())
          {
              cout << "Did not find B" << endl;
          }
      }
      

      【讨论】:

        【解决方案5】:

        我认为使用比较器函数是一种更优雅的解决方案。

        假设您将学生类定义为

        class Student {
        public:
            Student(int id) : id(id) { }
            Student(int id, std::string name) : id(id), name(name) { }
            int id;
            std::string name;
        };
        

        那么你可以在创建集合时定义一个比较器函数,然后在 find 中使用它。在这种情况下,此函数具有签名 bool (Student, Student)

        int main() {
            std::set<Student, std::function<bool (Student, Student)>> data(
                    [](Student a, Student b) {
                        return a.id < b.id;
                    });
            data.insert(Student(1, "foo"));
            data.insert(Student(2, "bar"));
            data.insert(Student(3, "foobar"));
        
            std::set<Student>::iterator it = data.find(Student(2));
        
            std::cout << "Element found with id " << it->id << " and name " << it->name << std::endl;
        
            return 0;
        }
        

        这种情况下的输出是

        Element found with id 2 and name bar
        

        编辑:此外,您可以检查是否找到了元素

        if (it != data.end()){
            // found
        } else {
            // not found
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-14
          • 2020-04-07
          • 2012-05-12
          • 1970-01-01
          相关资源
          最近更新 更多