Reputation: 1777
Firstly, this is an assignment with artificial restrictions. The assignment tasks me to use STL, inheritance, and polymorphism. I also must use iterators to find, print and delete items from the list based on the object id.
I'm using a list of pointers to objects. These objects are derived from a abstract base class Sequence, and are being dynamically allocated and stored in the list.
My abstract base class
class Sequence{
public:
virtual void print() = 0;
virtual int getId() = 0;
protected:
std::string m_label;
int m_id;
std::string m_sequence;
int m_length;
};
The print()
and getId()
functions are overridden in the derived classes. The data is being read in from a file and parsed by commands on each line.
SequenceDatabase::SequenceDatabase(){
std::list<Sequence*> myList;
}
// function reads in the filename creates a data stream and performs the requested actions
void SequenceDatabase::importEntries(std::string inputFile){
std::ifstream dnaFile(inputFile);
char command;
std::string label, sequence, type;
int id, length, index, orf;
while(dnaFile >> command){
Sequence* s;
// if the command = D this allocates memory for a dna object and pushes the object onto the list
if(command == 'D'){
dnaFile >> label >> id >> sequence >> length >> index;
std::cout << "Adding " << id << " ...\n\n";
s = new DNA(label, id, sequence, length, index);
myList.push_back(s);
}
// if the command = R this allocates memory for a RNA object and pushes the object onto the list
if(command == 'R'){
dnaFile >> label >> id >> sequence >> length >> type;
std::cout << "Adding " << id << " ...\n\n";
s = new RNA(label, id, sequence, length, type);
myList.push_back(s);
}
// if the command = A this allocates memory for an AA object and pushes the object onto the list
if(command == 'A'){
dnaFile >> label >> id >> sequence >> length >> orf;
std::cout << "Adding " << id << " ...\n\n";
s = new AA(label, id, sequence, length, orf);
myList.push_back(s);
}
// if the command = O this searches the list for the id and either outputs that the object doesn't exist or it deletes it
if(command == 'O'){
dnaFile >> id;
std::cout << "Obliterating " << id << " ...\n\n";
// problem
}
// if the command = P this searches the lists for the id and either outputs that the object doesn't exist or it prints out the info of the object
if(command == 'P'){
dnaFile >> id;
std::cout << "Printing " << id << " ...\n";
// problem
}
// if the command = S this outputs the number of entries in the list
if(command == 'S')
std::cout << "Entries: " << myList.size() << " total\n";
}
dnaFile.close();
}
The list is being built correctly. My problem arises when trying to search the list for an object with a certain id. I created the findId()
function because I know i have to compare that to the id read in.
I'm not sure how to use the std::find
or std::find_if
functions when dealing with object pointers. I've tried for hours and every thing i tried doesn't compile.
Any help is appreciated. Thank you!
Upvotes: 1
Views: 2270
Reputation: 12641
In case you don't have access to a C++11 compiler or you don't want to use lambda functions, you could define a comparator
struct Comparator {
id_type find_id;
Comparator(id_type id) : find_id(id) {}
inline bool operator ()(const Sequence * obj) {
return find_id == obj->getId();
}
}
. . .
typename std::list<Sequence *>::iterator it;
it = std::find_if(List.begin(), List.end(), Comparator(id));
return it != List.end();
Upvotes: 1
Reputation: 206567
If you have access to a C++11 compiler, you can use:
auto iter = std::find_if(myList.begin(),
myList.end(),
[](Sequence* s) -> bool { return (s->getId() == id); });
if ( iter != myList.end() )
{
return *iter;
}
else
{
return nullptr;
}
std::find_if
searches for an element for which predicate returns true
. Additional information can be found at http://en.cppreference.com/w/cpp/algorithm/find.
In this case, the predicate is a lambda function that returns true
if the given ID matches in the ID of one of the Sequence*
objects.
If the list doesn't contain a matching Sequence*
, find_if
returns myList.end()
.
Upvotes: 5
Reputation: 1
You could use something like
for (Sequence* p : myList)
if (p->getId()>50) dosomething(p);
BTW, you may want to use a list of smart pointers (e.g. std::shared_ptr) so
std::list<std::shared_ptr<Sequence>> myList;
Upvotes: 1