CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2007
    Posts
    34

    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.
    Last edited by Yadrif; October 21st, 2008 at 02:36 PM. Reason: typo correction

  2. #2
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    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.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  3. #3
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    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.
    Thanks for your help.

  4. #4
    Join Date
    Oct 2006
    Location
    Singapore
    Posts
    346

    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;
    	}
    Believe in your Dreams, Work for what you Believe in.
    My thoughts? Angelo's Stuff
    Some fun things I've done: RayWatch, QuickFeed, ACSVParser

    @ngelo

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured