Jump to content


C++ Assignment Operator


5 replies to this topic

#1 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 27 May 2007 - 07:00 AM

I was playing around with the assignment operator and discovered you can't implicitly inherit an assignment operator from base class.

class Base
{
public:
  int m_Data;
  const Base& operator=(int pData)
  { m_Data = pData; return *this;}
};

class ChildOne : public Base
{
public:
  void someFunc() {};
};

class ChildTwo : public Base
{
public:
  void someFunc() {};
  using Base::operator=;
};

int main()
{
  ChildOne l_1;
  ChildTwo l_2;

  l_1 = 1;
  l_2 = 2;

  return 0;
}

Quote

"ComeauTest.c", line 27: error: no operator "=" matches these operands
operand types are: ChildOne = int
l_1 = 1;
^
It seems to me like there's only one overload of operator= which really should be hidden:

Quote

-1- An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (class.copy), a base class assignment operator is always hidden by the copy assignment operator of the derived class.
This line from the standard says that the copy assignment operator will automatically be hidden, not all assignment operators.

If my Base::operator=(int) is automatically hidden, is there some reason why 'unhiding it' as done in ChildTwo is dangerous? (possibly automatic type conversions :unsure: )

#2 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 27 May 2007 - 07:03 AM

While still looking into operator= i came across a few other rules worth noting:

  • Copy assignment must check for assigning to itself(especially when using pointers)
    const Base& operator=(const Base& pBase)
    {
      if( &pBase == this ) return *this;
      // Do Stuff
      { delete m_Data; m_Data = new pBase.m_Data; } // for example
    }
    
  • operator= should take a const reference for it's parameter.
    Base &l_lval;
    const Base &l_rval;
    l_val = l_rval; // overloads such as operator=(Base &) would cause an error here.
    
  • Returning a non-const reference facilitates unreadable code
    Base &Base::operator=(const Base&){}; // instead of const Base&::operator=(const Base&)
    
    Base l_1, l_2, l_3;
    
    (l_1 = l_2) = l_3; // equivalent to: l_1.operator=(l_2); l_1.operator=(l_3);
    


#3 roel

    Senior Member

  • Members
  • PipPipPipPip
  • 678 posts

Posted 27 May 2007 - 08:22 AM

Just wait until .oisyn reads this thread ;)

#4 donBerto

    Senior Member

  • Members
  • PipPipPipPip
  • 369 posts

Posted 27 May 2007 - 02:53 PM

That's an interesting question. I always presumed that since a child class is essentially a new class, that the shallow-copy assignment operator is the default, until overridden (again).

The more I think about it, the more I agree with the 'hiding' mechanism of it. Why should a child class be able to implicitly inherit the assignment operator when the child class will (presumably) have different elements? This is why I believe the shallow-copy assignment operator then becomes the default until overridden.
Imagine.

#5 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 27 May 2007 - 05:27 PM

I'd think the default assignment operator for a subclass should consist of the assignment operator for its base class (whatever that is) and then shallow copies for any new data members.

If you write an assignment operator for the subclass, you can call the base class assignment operator as well, probably infixed to the subclass's own assignment actions.
reedbeta.com - developer blog, OpenGL demos, and other projects

#6 .oisyn

    DevMaster Staff

  • Moderators
  • 1810 posts

Posted 29 May 2007 - 10:17 AM

Actually, your code is perfectly fine, and your compiler sucks :)
Sorry I misread your post. I thought your compiler (which I now see is Comeau, which definitely doesn't suck at all ;)) was complaining while having the using declaration in your code.

But the reason is this: a function in a derived class hides all functions with the same name from it's base class. An auto-generated copy assignment operator is no exception to this rule.

Quote

This line from the standard says that the copy assignment operator will automatically be hidden, not all assignment operators
No, that line from the standard says that any base class assignment operator will be hidden by the (implicitely generated) copy assignment operator in the derived class :)

roel said:

Just wait until .oisyn reads this thread ;)
Done ;)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users