How to access class data in a set of pointers to that class

77 views Asked by At

I have a set of pointers:

set<StudentInterface*, Comparator> studentSet;

These pointers point to Student classes which inherit from StudentInterface and contain an int value ID. I want to test if a certain class has a particular value for ID. My current idea for doing so is as follows:

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

Is there a way to access the data elements this way? If not, what is the shortest way (in lines of code) that I can access these elements to test them?

5

There are 5 answers

3
shreyans800755 On BEST ANSWER

I don't think you can search for a particular element value of a class using find function from any STL container like vector/set/map.

You can do this in following manner :

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

Or if you can make a object to search, then you can do same thing as you asked in question :

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

Ran out of time. No point to using a set and then searching the set manually. Might as well use a vector. Here is the framework of a better way:

#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;
    }
}
0
ipa On

I think there is in my opinion a more elegant solution by using a comparator function.

Given you have the class Student defined as

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

then you can define a comparator function when creating the set, which is then used in find. In this case this function has the signature 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;
}

The output in this cas would be

Element found with id 2 and name bar

EDIT: Additionally you can check if an element was found by

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

Okay I have a tentative answer to this question. I can use the following to search the set for the desired element:

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

Not sure if that's the best way but I think it works.

0
Ediac On

You can also use set's iterator which comes included with the libraries. For example, given the set studentSet, you can:

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

This for will iterate from the first element of studentSet until the last element, with it receiving the object stored. Also, it will be receiving a reference(pointer) to the element.