dcsimg
Login | Register   
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Tip of the Day
Home » Tip Bank » C++
Language: C++
Expertise: Beginner
May 2, 1997

WEBINAR:

On-Demand

Application Security Testing: An Integral Part of DevOps


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 special member 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 classes that don't define them (when it can — but that's another story); the rules for that 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 for the assignment to be virtual, because it's not even visible to the clients of the 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 derived class, 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 the base 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 just
the base class subobject.
DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
×
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date