Thread: Question about Copy Constructor and Overloading Assignment Operator

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    25

    Question about Copy Constructor and Overloading Assignment Operator

    Hi everbody,
    I'm self-studying C++, so there are some points confusing me. Please help me make it clear:

    Consider this Copy Constructor Declaration:
    MyClass(const MyClass& myObj);

    Why must a copy constructor have call-by-reference parameter ? what happens if that is call-by-value parameter ? If call-by-value, will the compiler assign the parameter to another copy of the argument, and their pointers (pArr) will be pointing to the same array in memory that will later be destroyed by the destructor, when the temporary myObj goes out of scope once Copy Constructor finishes its job ?

    Code:
    MyClass
    {
      public:
      /* ....  */
      MyClass(const MyClass& myObj);
      ~MyClass();
      operator=(const Myclass& rsideObj);
      /* ...  */
      private:
      /* ... */
      char *pArr; /* used to create  dynamic array type of char (a C_string, I mean ... */
    };
    Why operator=(const MyClass& rsideObj) must be a member function, rather than friend function, just like other overloading operators?
    Last edited by trongsi; 05-19-2006 at 02:15 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Why must a copy constructor have call-by-reference parameter ? what happens if that is call-by-value parameter ?
    I am guessing that passing the copy constructor argument by value is not possible.

    Why operator=(const MyClass& rsideObj) must be a member function, rather than friend function, just like other overloading assignment ?
    Actually, I think other overloaded assignment operators should also be member functions.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by trongsi
    Why operator=(const MyClass& rsideObj) must be a member function, rather than friend function, just like other overloading assignment ?
    Making it a friend isn't sensible. Good OOP design is keeping your data as safe and as unchanged as possible: if you made operator= a friend function, you would have to pass in references to both sides of the operator, and make changes to both of those. Plus, the assignment operator needs access to the class' private members, and making it a member avoids the overhead of calling getter functions.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    25
    Thanks for your reponses, back to the first question, why does C++ require the copy constructor and overloading assignment operator having call-by-reference parameter. Is the reason I listed above the major problem that makes them not having call-by-value ?

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    If you tried to do this with call by value, it would be an unnecessary headache, and to be honest it doesn't make any sense either, since your assignment operator didn't create anything it's working with.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by trongsi
    back to the first question, why does C++ require the copy constructor and overloading assignment operator having call-by-reference parameter.
    Well, if your "copy constructor" isn't by reference, then needs to make a copy using the copy constructor, which needs to make a copy using the copy constructor, which needs to make a copy using the copy constructor, which needs to make a copy...
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    25
    Well, Thanks Dave_Sinkula.

    Are following definition of Overloading Operator Assignment equivalent ?
    Why must the second one's return type be MyClass&, not MyClass ? What does it mean with that return type ?

    Code:
    //The first one, assume that its declaratoin including in class interface
    
    void MyClass::operator=(const MyClass& rsideObj)
    {
       if (this==&rsideObj) //check if rightside is leftside object itself.
    	return;
       else
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
    }
    
    
    //the altinative
    
    MyClass& MyClass::operator=(const MyClass& rsideObj)
    {
       if (this==&rsideObj) //check if rightside is leftside object itself.
    	return *this;
       else
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
    	return *this;
       }
    }
    Thanks in advance for helping me, and please patient with me...
    Last edited by trongsi; 05-19-2006 at 06:28 PM.

  8. #8
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    I don't think that there's any requirement, its just that references
    are far more efficient. Also your assignment code is wrong:

    Code:
    void MyClass::Operator=(const MyClass& rsideObj)
    {
       if (this!=&rsideObj) //check if rightside is leftside object itself.
    	exit(1);
       else
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
    }
    should actually be this:

    Code:
    void MyClass::Operator=(const MyClass& rsideObj)
    {
       if (this!=&rsideObj) //check if rightside is leftside object itself.
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
       return;
    }
    similarly, your alternative will be this:

    Code:
    MyClass& MyClass::Operator=(const MyClass& rsideObj)
    {
       if (this!=&rsideObj) //check if rightside is leftside object itself.
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
       return *this;
    }
    See why?

    [update]
    operator is a keyword - not Operator.
    [/update]
    Last edited by Richie T; 05-19-2006 at 04:34 PM.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by trongsi
    Are following definition of Overloading Operator Assignment equivalent ?
    Why must the second one's return type be MyClass&, not MyClass ? What does it mean with that return type ?
    Returning a reference allows assignment chaining.
    Maybe wander around the C++ FAQ LITE (I have been):
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    25
    Quote Originally Posted by Richie T
    I don't think that there's any requirement, its just that references
    are far more efficient. Also your assignment code is wrong:

    Code:
    /*Correction for my previous wrong posting */
    void MyClass::operator=(const MyClass& rsideObj)
    {
       if (this==&rsideObj) //check if rightside is leftside object itself.
    	return;
       else
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
    }
    should actually be this:

    Code:
    void MyClass::operator=(const MyClass& rsideObj)
    {
       if (this==&rsideObj) //check if rightside is leftside object itself.
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
       return;
    }
    similarly, your alternative will be this:

    Code:
    MyClass& MyClass::Operator=(const MyClass& rsideObj)
    {
       if (this!=&rsideObj) //check if rightside is leftside object itself.
       {
    	delete [] pArr;
    	pArr = new char[strlen(rsideObj.pArr) + 1];
    	strcpy(a,rsideObj.pArr);
       }
       return *this;
    }
    See why?

    [update]
    operator is a keyword - not Operator.
    [/update]
    Yes yes, You're so right. I made some mistakes when I posted these code. However, I meant that those function work exactly alike, don't them ?
    Thanks all for your helping.
    Last edited by trongsi; 05-19-2006 at 06:28 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Crazy Assignment Operator Semantics
    By SevenThunders in forum C++ Programming
    Replies: 7
    Last Post: 01-22-2009, 01:08 PM
  2. Copy constructor question
    By BigFish21 in forum C++ Programming
    Replies: 9
    Last Post: 05-04-2008, 12:18 PM
  3. operator overloading question
    By brianptodd in forum C++ Programming
    Replies: 2
    Last Post: 05-09-2003, 09:03 PM
  4. int vs BIG INT
    By rumi_red in forum C++ Programming
    Replies: 1
    Last Post: 10-30-2001, 04:15 AM