Thread: class question

  1. #1
    Registered User
    Join Date
    Apr 2002
    Posts
    139

    class question

    I need to create a clone of a class (the same class as my earlier vector topic)

    the call looks like this:
    Code:
    clone_test=List_Num_1.clone();
    in my class the clone() is the following:
    Code:
      CNameValueList CNameValueList::clone()
      {
        CNameValueList temp;
        string strValue;
        string strName;
        for (MYVECTORITER the_iterator=list.begin(); the_iterator != list.end(); the_iterator++)
        {
          strValue=(*the_iterator)->getValue();
          strName=(*the_iterator)->getName();
          temp.add(strName,strValue);
        }
        return temp;
      }
    Upon returning "temp" it crashes...
    Can anyone give me a hint as to why this code doesn't work?
    "The most common form of insanity is a combination of disordered passions and disordered intellect with gradations and variations almost infinite."

  2. #2
    Registered User foniks munkee's Avatar
    Join Date
    Nov 2001
    Posts
    343
    I would suggest that it is because temp does not exist outside of the scope of the member function clone()

    You should be allocating memory for the class and returning a pointer to the object.
    "Queen and huntress, chaste and fair,
    Now the sun is laid to sleep,
    Seated in thy silver chair,
    State in wonted manner keep."

  3. #3
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    >CNameValueList CNameValueList::clone()

    If you return an object, not a pointer, the program will copy your object from temp to the object you asign the result to. If you don't have a copy constructor or operator =, this will probably fail because it will copy the class bitwise. Use a pointer as stated above.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    139
    Code:
    CNameValueList CNameValueList::clone()
    {
      CNameValueList* temp=new CNameValueList;
      string strValue;
      string strName;
    
      for (NVPLISTITER the_iterator=list.begin(); the_iterator != list.end(); the_iterator++)
      {
        strValue=(*the_iterator)->getValue();
        strName=(*the_iterator)->getName();
        temp->add(strName,strValue);
      }
      return *temp;
    }
    This is what I currently have. It copies fine, but 2 errors occur.

    1: If I add a new value to my cloned class, it overwrites the the other data.

    2: Upon completion of the program it crashes.

    thanks (still churning away at it)

  5. #5
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Your crash problem stems from what I was telling you in the other thread....if you have a vector of pointers, you must take special care!.....if you copy the vector to another, then the new vector recieves copies of the pointers...therefore, to pointers exist for each object on the heap....and if 1 vector calls delete on the object before going out of scope, then the second vector now refers to data that could cause a crash if its dereferenced or deleted!!!!

    To get around this, your clone function must implement a deep copy to create more objects on the heap as opposed to copying references to single objects.....

    Also, if you are using a clone function, you might want to keep an eye out for the copy constructor and operator=()...they must either do a deep copy too, or be made private and unusable...

    Here is the code from the earlier thread.......I altered it a little to show how you can implment the Clone function

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <utility>//for std::pair
    using namespace std;
    
    
    class foobar{
    	typedef vector<pair<string, string>* > MYVECTOR;
    	typedef MYVECTOR::iterator MYVECTORITER;
    	
    	foobar(const foobar&);//Make private...rely on foobar::Clone
    	const foobar& operator=(const foobar&);//Make private...rely on foobar::Clone
    	
    	MYVECTOR vec;
    public:
    
    	foobar(){}//Need this as made copy constructor private
    
    	void AddPair(const string& lhs,const string& rhs){
    		pair<string,string>* temp = new pair<string,string>(lhs,rhs);	
    		vec.push_back(temp);
    	    ToScreen();
    	 }
       
        ~foobar(){//destructor
        	
    			for(int i = 0;i < vec.size();++i)
        			delete vec[i];//delete each
        	 
    
    	}
    	
    	void ToScreen(){//Add a print function
    	
    		MYVECTORITER the_iterator;
    		for (the_iterator = vec.begin();
    			the_iterator != vec.end();
    			++the_iterator){
    	        cout << (*the_iterator)->first << ' ';
    	        cout << (*the_iterator)->second << '\n';
    	    }
    	}
    	
    	void Clone(const foobar& rhs){
    	
    		
    			for(int i = 0;i < vec.size();++i)
        			delete vec[i];//delete each
    		vec.clear();//empty current vector
    				
    		for (int i = 0;i < rhs.vec.size();++i){//Deep copy
    	        pair<string,string>* temp = new pair<string,string>(*rhs.vec[i]);
    			vec.push_back(temp);
    	    }	
    	}
    
    };
    
    int main(){
    
    	foobar f;
    	
    	f.AddPair("Hello","World");
    	
    	cout << endl;
    	
    	f.AddPair("Eat at","Joes");
    	
    	cout << endl;
    	
    	f.AddPair("foo","bar");
    	
    	cout << endl << "From g (cloned from f)" << endl;
    	
    	foobar g;//make a new foobar
    	
    	g.Clone(f);//copy f members to g
    	
    	g.ToScreen();//print out all of g
    	
    	cout << endl << "From h (cloned from g)" << endl;
    	
    	foobar h;
    	
    	h.Clone(g);//Yet another copy
    	
    	h.ToScreen();
    
    
    }

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    139
    I understand about the having to create a new "hard" copy of the list and each value pair but I guess i'm confusing myself.

    I need to have it so that the following can happen:
    a=b.clone();

    So inside my function clone() i need to:
    1) create a new CNameValueList object.
    2) copy all values from the current object into the new object.
    3) return the new object.


    so in my CNameValueList::Add(str1,str2) I have :
    Code:
    CNameValue* temp2=new CNameValue(strName,strValue);
    list.push_back(temp2);
    and in my CNameValueList::clone() I have :
    Code:
    CNameValueList CNameValueList::clone()
    {
      CNameValueList* temp2=new CNameValueList;
      string strValue;
      string strName;
    
      for (NVPLISTITER the_iterator=list.begin(); the_iterator != list.end(); the_iterator++)
      {
        strValue=(*the_iterator)->getValue();
        strName=(*the_iterator)->getName();
        temp2->add(strName,strValue);
      }
      return *temp2;
    }
    Questions:
    So have I done the right thing with the function I have created?
    The way I see it (which must be missing something cuz it has an error) is that:
    1- It creates a new CNameValueList
    2- It gets the values from the old list.
    3- It pushes(creates) new CNameValue objects onto the new list
    4- It returns the newly created list

    Is that what you mean?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  2. Replies: 8
    Last Post: 10-02-2005, 12:27 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. question about DLL's and class functions
    By btq in forum Windows Programming
    Replies: 2
    Last Post: 02-25-2003, 06:08 AM
  5. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM