Saiful Islam
Saiful Islam

Reputation: 159

c++: check for an object of a class in an array of objects

suppose i have a class Element which is,

class Element {
private:
    int value;
public:
    void setValue(int v) {
        value = v;
    }
    int getValue() {
        return value;
    }
};

and i store the objects of this class in an array. Now how can i check if my array of object contains a certain object of class Element.I have tried matching the values of the object using this function...is there any better ways?

bool contains(Element e)
{
    int i;

    for(i=0;i<size;i++)
        if(elements[i].getValue()==e.getValue()) return true;
    else return false;
}

Upvotes: 3

Views: 6483

Answers (5)

Topological Sort
Topological Sort

Reputation: 2787

Although the above answers may be good for expert programmers, I believe at your level, Adkison, you would like a simpler response.

bool contains(Element e)
{
    int i;

    for(i=0;i<size;i++)
        if(elements[i].getValue()==e.getValue()) return true;
    else return false;
}

OK, so one problem is that elements doesn't have a value, and neither does size. It should be passed in as a parameter. We'll also use const-& on e, so that it need not be copied (although that's not a big cost here).

bool contains  (const Element elements[], int size, const Element& e) ...

(Yes, we could pass in elements as a vector, but let's keep it simple for now.)

I believe the problem you're noting is that it never gets past looking at the 0th element. Trace through and you'll see why. Suppose that element #0 is equal to e; your function returns true, and is done. Suppose that it isn't equal: your function returns false, and is done. What about all the other elements? Shouldn't we check them too, at least if element #0 isn't what we wanted?

So: when should we return false? When when we've gone thru the whole list and not found e.

    for(i=0;i<size;i++)
        if(elements[i].getValue()==e.getValue()) return true;

    return false;

This version doesn't return false until it's looked through the whole array, and failed to find e.

Upvotes: 0

cdonat
cdonat

Reputation: 2822

First you can implement the equal-comparison operator

class Element {
private:
    int value;
public:
    // btw. These setters and getters are Java style, not C++ style.
    void setValue(int v) {
        value = v;
    }
    // note that a getter should be const. It doesn't change the object.
    auto getValue() const -> int {
        return value;
    }
    auto operator == (const Element& other) const -> bool {
        return value == other.value;
    }
    auto operator != (const Element& other) const -> bool {
        return !(*this == other);
    }
};

Now you can use std::find():

auto contains(const Element& e) -> bool
{
    auto end = elements + size; // pointers can be used as iterators as well.
    return std::find(elements, end, e) != end;
}

You should prefer std::vector or std::array over raw arrays. std::array does not add any overhead but makes the interface more consistent with other std::-containers. std::vector is used for dynamically sized arrays. It handles all the allocation, initialization, destruction, deallocation, etc. for you.

Upvotes: 0

Lorenzo Belli
Lorenzo Belli

Reputation: 1847

You could use a C++ container like std::array and then use std::find_if.

If you prefer to extend your code, you could overload the operator== using

bool operator==(const Element& lhs, const Element& rhs) {
    return lhs.value == rhs.value
}

then you can use

for(i=0;i<size;i++)
    if(elements[i]==e) return true;

EDIT:

since Element.value is private you may want to make this a method of Element

bool Element::operator==(const Element& other) {
    return value == other.value
}

Upvotes: 2

Connor Hollis
Connor Hollis

Reputation: 1155

You can add comparison operators to your element class and then use stl algorithms or stl like algorithms to determine if an element is in the container.

class Element {
private:
    int value;
public:
    Element(int v) : value(v) {}
    Element(Element const& e) : value(e.value) {}

    Element & operator=(Element const& e) {
        value = e.value;
    }

    bool operator==(Element const& e) const {
        return value == e.value;
    }

    bool operator!=(Element const& e) const {
        return value != e.value;
    }

    void setValue(int v) {
        value = v;
    }
    int getValue() {
        return value;
    }
};

Now you can do something like this.

std::vector<Element> elements;

for(int i = 0; i < 10; ++i) {
    elements.push_back(Element(i));
}

 // Find the element with the value 4
auto found = std::find(elements.begin(), elements.end(), Element(4));
if(found != elements.end()) {
    // Do something
}

Or use a loop like what you described.

Element toFind(4);

for(auto it = elements.begin(); it != elements.end(); ++it) {
     if(*it == toFind) {
       // Do something
     }
}

Upvotes: 0

Mohamad Elghawi
Mohamad Elghawi

Reputation: 2124

I would suggest using a C++ container like stds::array or std::vector to hold your elements and using std::find_if to search through it.

If you are using a compiler that supports C++11 syntax then you can use std::find_if like this:

int main () 
{
    std::vector<Element> myvector;

    // fill vector

   int valueToCompare = 1234;

   auto it = std::find_if(begin(myvector), end(myvector), [=](const Element& e) {return e.getValue() == valueToCompare;});

   return 0;
}

Upvotes: 0

Related Questions