1

I have some code which adds a few objects to a vector. I then wish to retrieve a specific object from the vector and be able to both write out and edit its private member variables.

This is the code I currently have:

class Product {
public:
    Product(int n, const string& na, int p)
            : number(n), name(na), price(p) {};
    void info() const;
private:
    string name;
    int number, price;
};

The member function looks like this:

void Product::info() const {
    cout << number << ". " << name << " " price << endl;
}

I then create a vector and push into it some objects, like so:

vector<Product> range;
range.push_back(Product(1, "Bagpipe", 25));

To retrieve and list the information about all objects, I have the following function:

void listProducts (const vector<Product>& range1) {
    for_each (range1.begin(), range1.end(), mem_fun_ref(&Product::info));
}

But this is where I get stuck.

To boil my problem down: I have no idea how to retrieve individual objects from the vector and edit them. I need to be able to search my vector for objects containing a specific number or name, and be able to retrieve either the information about all its private members, and also be able to edit all members.

Ideas I have about solutions thusfar are:

  • to create additional member functions that can return individual members

  • to create functions that, similar to the function I already have above, can search through each object in the vector and use the return from these additional member functions to compare with what I'm looking for

  • I don't quite know how I would go about editing an objects private members, but my current guess is that I would need members functions for this as well, and functions that tie in to those

Any help would be greatly appreciated! Even vague nudges in the right direction!

vaent
  • 11
  • 3

4 Answers4

3

If the member variables are private, then by definition, you cannot access them from the outside world! You will need to do one of the following:

  • Change them to public.
  • Add accessor functions to the class (i.e. int MyClass::getFoo() const and void MyClass::setFoo(int)).
  • Make your function a friend of the class.

This is nothing to do with being stored in a vector.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • Say I create three accessor functions the return the value of both number, name and price. I then need a way to call this member function for each object stored in the vector. `for_each` which I used above doesn't do the job, as I need to compare each value returned. Mark B below suggested `find_if`, but I can't seem to find a way to use it in conjunction with my accessor functions. Got any further nudges in the right direction? I feel as if I'm so close to an answer, yet so far! – vaent Apr 29 '11 at 21:17
1

You can use std:find_if to find items in a vector based on any criteria you wish.

Then you can add a public interface to Product to allow you to update its state as needed. Note that this interface need not be a direct "set this item to this value" mapping.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • Do you know how and if I could use `find_if` with the return value from an accessor function as criteria? – vaent Apr 29 '11 at 21:18
0

Boost.MultiIndex with an index for each searchable field might be easier than using a vector with your own search code.

The Boost Multi-index Containers Library provides a class template named multi_index_container which enables the construction of containers maintaining one or more indices with different sorting and access semantics. Indices provide interfaces similar to those of STL containers, making using them familiar. The concept of multi-indexing over the same collection of elements is borrowed from relational database terminology and allows for the specification of complex data structures in the spirit of multiply indexed relational tables where simple sets and maps are not enough. A wide selection of indices is provided, modeled after analogous STL containers like std::set, std::list and hashed sets.

I also echo comments about private member access in other answers.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • I really don't think this addresses what the OP is asking about. –  Apr 29 '11 at 18:49
  • Nope, but it's relevant to the bigger problem OP is trying to solve, which is locating a given `Product` instance based on different criteria. Quote: `I need to be able to search my vector for objects containing a specific number or name` – Steve Townsend Apr 29 '11 at 18:51
0

You need to either provide member functions for your Product class that allow the Product properties to be changed OR BETTER replace the Product object in the vector with the results of editing an existing one, but to do that you need to provide accessor functions, or suitable constructors in your Product class.