-
Iterator Question
Hello Everyone,
I would like to return a pointer to an object that is found in a set. Here is the code:
Code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <set>
using namespace std;
class KeyValue
{
public:
KeyValue(string key, string value) : _key(key), _value(value) {
}
string getName() const { return this-> _key; }
string getValue() const { return this-> _value; }
bool operator==(const KeyValue& other) const
{
return (this->_key == other.getName());
}
bool operator<(const KeyValue& other) const
{
return (this->_key < other.getName());
}
private:
string _key;
string _value;
};
class KeyValueSet
{
public:
KeyValueSet() {
// put some KeyValue's in the set just for testing
KeyValue kv1("Dog", "Hound");
KeyValue kv2("Cat", "NoGood");
KeyValue kv3("Fish", "Bass");
theSet.insert(kv1);
theSet.insert(kv2);
theSet.insert(kv3);
}
KeyValue* getKeyValue(string & name, string & value)
{
KeyValue key_value(name, value);
KeyValue * ret = 0;
// find by name only, if not found use value as default
set<KeyValue>::iterator iter = theSet.find(key_value);
if (iter != theSet.end()) {
//ret = iter; // compile error
ret = const_cast<KeyValue*>(&(*iter)); // Is there a better way to do this?
} else {
ret = new KeyValue(name,value);
}
return ret;
}
private:
set<KeyValue> theSet;
};
int main(int argc, char *argv[])
{
KeyValueSet kvs;
string s1("Fish");
string s2("Bass");
KeyValue* kv = kvs.getKeyValue(s1, s2);
system("PAUSE");
return 0;
}
Is there an easier way to do this other than the line:
retval = const_cast<KeyValue*>(&(*iter));
I tried the line above it but get a compile error. I think I understand why after do some reading but it seems like there would be an easier way to return the pointer to the object.
All help is appreciated.
Thanks.
-
Re: Iterator Question
In general you do NOT want to do this.
1) What happens if the set (which owns the object) goes out of scope while you are still holding a pointer.
2) (If the pointer is non-const), what happens if you modify the value such that it violates the contraint of the set.
The proper thing to do is to return a copy of the actual item in the set.
-
Re: Iterator Question
Code:
KeyValue * ret = 0;
You cannot declare a local copy pointer to local variable and return that pointer because the pointee is out of scope or when stack unwinding.
What is stack unwinding ? Simplified explanation needed. Thanks for your help.
This has been pointed by TheCPuWizard.
I hope this help.
-
Re: Iterator Question
Btw, your code has a memory leak. You do a new in the getKeyValue() function and never do a delete on the pointer that's returned.
I'd suggest not returning by reference at all, instead return by value.
Code:
const KeyValue getKeyValue(const string &name, const string &value)
{
KeyValue keyValue( name, value );
std::set<KeyValue>::const_iterator iter = theSet.find( keyValue );
if( iter != theSet.end() )
return *iter;
return keyValue;
}