devxlogo

Inherited operator = not being seen

Inherited operator = not being seen

Question:
I have a templated class A that defines two operator =, and a templated class B : public class A which should inherit the two virtual a::operator = I define, but when I instantiate an object B b, it won’t see the operator = .

Answer:
You are not going to like this, but the operator = is a specialmember function that is not inherited, in order to prevent slicing of objects.

Consider:

struct Base{	const Base& operator=(const Base& b) {i = b.i;};private:	int i;};struct Derived : public Base{private:	int i;};
If the assignment were to be inherited, I could then say:Derived d1,d2;d1 = d2;and only the Base subobject of d1 would get copied, not the Derived part.

To solve this problem, the compiler generates an assignment operator for classesthat don’t define them (when it can ? but that’s another story); the rules forthat is member-wise, copy starting with the base classes. So, the compiler-generated assignment operator would look something like this:

inline Derived& Derived::operator(const Derived& d){	Base::operator=(d);	i = d.i;	return *this;}
Note that the generated copy assignment operator is inline.

This interesting property of assignment operators also makes it impossible forthe assignment to be virtual, because it’s not even visible to the clients ofthe derived class.

So that was the gist of your problem; now, let’s try to work out a solution.

Let’s rewrite our example classes now and define operator = for the derivedclass, too.

struct Base{	const Base& operator=(const Base& b) {assign(b);return *this;};protected:	void assign (const Base& b) { i = b.i;}private:	int i;};struct Derived : public Base{	const Derived&  operator = (const Derived& d) {assign(d);return *this;};protected:	void assign(const Base& b) 	{		// call base classes assign		Base::assign(b);		try		{			const Derived &d = dynamic_cast(b);			i = d.i;		}		catch (const bad_cast&)		{			// do appropriate error handling		}	}private:	int i;};
So now if we have
Derived d1,d2;
and we say
d1 = d2; // this will call Derived::operator =() which calls assign and // propagates all the way to the base class and then copies itself.
This has the added advantage of making the assignment operator in thebase class behave polymorphically. For example, if we had
Base * b1 = new Derived;Base * b2 = new Derived;
*b1 = *b2; // would still get the entire object assigned, as opposed to justthe base class subobject.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist