Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > operator=() in base and derived class

Reply
Thread Tools

operator=() in base and derived class

 
 
MWimmer
Guest
Posts: n/a
 
      10-22-2007
Dear members of this group,

recently I came across a problem with repsect to operator=() and
inheritance. Consider the following code snippet:

------------------------------------------------------------
#include <iostream>

using namespace std;

class A
{
public:
A & operator=(const A &_a) {
cout << " in A" << endl;
}
};

class B : public A
{
public:
B & operator=(const A &_a) {
cout << " in B" << endl;
A:perator=(_a);
}
};

main()
{
B b1, b2;
A a;

b1=b2;

cout << endl;

b1=a;
}
----------------------------------------

If you run this program (compiled using gcc 3.3 and 4.1), the output
you get is:

-------------------
in A

in B
in A
------------------

This means:
* for the assignment b1=b2, A:perator=() is invoked
* for b1=a, B:perator=() is invoked.

Now the solution to make the code behave as intended by me is to add
another function

B & operator=(const B&_B) {
cout << " in B" << endl;
A:perator=(_b);
}

However, I don't understand the reasons for this behaviour and I'd
like to understand that. What are the rationales behind that behaviour?

 
Reply With Quote
 
 
 
 
Uday Bidkar
Guest
Posts: n/a
 
      10-22-2007
In b1=b2, since you haven't provided an operator =() in class B that
takes an object of B, you get a default one from compiler which would
do bitwise copy of B's members. Since you have provided an operator
=() in A, the compiler generated operator =() calls this one to copy
A's members. Hence you see a call to A:perator=().

In b1=a, you have your own operator =() that takes object of class A
and hence this is the function that gets called.

-Uday Bidkar
MWimmer wrote:

> Dear members of this group,
>
> recently I came across a problem with repsect to operator=() and
> inheritance. Consider the following code snippet:
>
> ------------------------------------------------------------
> #include <iostream>
>
> using namespace std;
>
> class A
> {
> public:
> A & operator=(const A &_a) {
> cout << " in A" << endl;
> }
> };
>
> class B : public A
> {
> public:
> B & operator=(const A &_a) {
> cout << " in B" << endl;
> A:perator=(_a);
> }
> };
>
> main()
> {
> B b1, b2;
> A a;
>
> b1=b2;
>
> cout << endl;
>
> b1=a;
> }
> ----------------------------------------
>
> If you run this program (compiled using gcc 3.3 and 4.1), the output
> you get is:
>
> -------------------
> in A
>
> in B
> in A
> ------------------
>
> This means:
> * for the assignment b1=b2, A:perator=() is invoked
> * for b1=a, B:perator=() is invoked.
>
> Now the solution to make the code behave as intended by me is to add
> another function
>
> B & operator=(const B&_B) {
> cout << " in B" << endl;
> A:perator=(_b);
> }
>
> However, I don't understand the reasons for this behaviour and I'd
> like to understand that. What are the rationales behind that behaviour?


 
Reply With Quote
 
 
 
 
wyg
Guest
Posts: n/a
 
      10-22-2007
On Oct 22, 4:44 pm, MWimmer <(E-Mail Removed)> wrote:
> Dear members of this group,
>
> recently I came across a problem with repsect to operator=() and
> inheritance. Consider the following code snippet:
>
> ------------------------------------------------------------
> #include <iostream>
>
> using namespace std;
>
> class A
> {
> public:
> A & operator=(const A &_a) {
> cout << " in A" << endl;
> }
>
> };
>
> class B : public A
> {
> public:
> B & operator=(const A &_a) {
> cout << " in B" << endl;
> A:perator=(_a);
> }
>
> };
>
> main()
> {
> B b1, b2;
> A a;
>
> b1=b2;
>
> cout << endl;
>
> b1=a;}
>
> ----------------------------------------
>
> If you run this program (compiled using gcc 3.3 and 4.1), the output
> you get is:
>
> -------------------
> in A
>
> in B
> in A
> ------------------
>
> This means:
> * for the assignment b1=b2, A:perator=() is invoked
> * for b1=a, B:perator=() is invoked.
>
> Now the solution to make the code behave as intended by me is to add
> another function
>
> B & operator=(const B&_B) {
> cout << " in B" << endl;
> A:perator=(_b);
> }
>
> However, I don't understand the reasons for this behaviour and I'd
> like to understand that. What are the rationales behind that behaviour?


I copied some information from MSDN for you reference:
The assignment operator has some additional restrictions. It can be
overloaded only as a nonstatic member function, not as a friend
function. It is the only operator that cannot be inherited; a derived
class cannot use a base class's assignment operator.


 
Reply With Quote
 
MWimmer
Guest
Posts: n/a
 
      10-22-2007
On Oct 22, 11:24 am, Uday Bidkar <(E-Mail Removed)> wrote:
> In b1=b2, since you haven't provided an operator =() in class B that
> takes an object of B, you get a default one from compiler which would
> do bitwise copy of B's members. Since you have provided an operator
> =() in A, the compiler generated operator =() calls this one to copy
> A's members. Hence you see a call to A:perator=().
>
> In b1=a, you have your own operator =() that takes object of class A
> and hence this is the function that gets called.
>
> -Uday Bidkar


Ah, thanks a lot, that makes it clear!

 
Reply With Quote
 
Lance Diduck
Guest
Posts: n/a
 
      10-22-2007
On Oct 22, 4:44 am, MWimmer <(E-Mail Removed)> wrote:
> Dear members of this group,
>
> recently I came across a problem with repsect to operator=() and
> inheritance. Consider the following code snippet:
>
> ------------------------------------------------------------
> #include <iostream>
>
> using namespace std;
>
> class A
> {
> public:
> A & operator=(const A &_a) {
> cout << " in A" << endl;
> }
>
> };
>
> class B : public A
> {
> public:
> B & operator=(const A &_a) {
> cout << " in B" << endl;
> A:perator=(_a);
> }
>
> };
>
> main()
> {
> B b1, b2;
> A a;
>
> b1=b2;
>
> cout << endl;
>
> b1=a;}
>
> ----------------------------------------
>
> If you run this program (compiled using gcc 3.3 and 4.1), the output
> you get is:
>
> -------------------
> in A
>
> in B
> in A
> ------------------
>
> This means:
> * for the assignment b1=b2, A:perator=() is invoked
> * for b1=a, B:perator=() is invoked.
>
> Now the solution to make the code behave as intended by me is to add
> another function
>
> B & operator=(const B&_B) {
> cout << " in B" << endl;
> A:perator=(_b);
> }
>
> However, I don't understand the reasons for this behaviour and I'd
> like to understand that. What are the rationales behind that behaviour?


The compiler will implicily create an assignment operator, that just
calls assignment for member and base.
The only way not to get this is to define one yourself, that takes the
type as an argument. In this case, B&operator=(A const&); does not
turn off this implictly generated function.

The complier made up a function for you that looks like
B&operator=(B const&b){
A:perator=(b);
}


Why does it do this? This is more to support some coding styles that
are essentially mixtures of C and C++. So in C we may have

struct A{
int g;
char buf[123];
};
struct B{
A a;//C version of inheritance
double d[543];
};
void foo(){
struct B b1,b2;
b1=b2;//C does a implicit memcpy underneath the hood

}
So you can see that the "implicit operator=" is a holdover from C.
when this is converted to C++, it may look like

struct A1{
int g;
std::string buf;
};
struct B1:A1{
std::vector<double> d;
};

void foo1(){
struct B1 b1,b2;
b1=b2;//C++ does a member by member operator= underneath the hood
//because string and vector will not survive a memcpy
}



Lance

 
Reply With Quote
 
anon
Guest
Posts: n/a
 
      10-22-2007
My comment will not change behavior of your classes, but aren't you
missing something here?

MWimmer wrote:
> class A
> {
> public:
> A & operator=(const A &_a) {
> cout << " in A" << endl;

return *this;
> }
> };
>
> class B : public A
> {
> public:
> B & operator=(const A &_a) {
> cout << " in B" << endl;
> A:perator=(_a);

return *this;
> }
> };
>

 
Reply With Quote
 
MWimmer
Guest
Posts: n/a
 
      10-22-2007
On Oct 22, 11:44 am, anon <(E-Mail Removed)> wrote:
> My comment will not change behavior of your classes, but aren't you
> missing something here?
>
>
>
> MWimmer wrote:
> > class A
> > {
> > public:
> > A & operator=(const A &_a) {
> > cout << " in A" << endl;

> return *this;
> > }
> > };

>
> > class B : public A
> > {
> > public:
> > B & operator=(const A &_a) {
> > cout << " in B" << endl;
> > A:perator=(_a);

> return *this;
> > }
> > };


Yes I did miss the return *this - I forgot to add it in this made up
example.

Thanks guys, you've been very helpful, now i understand the problem

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      10-23-2007
On Oct 22, 11:24 am, Uday Bidkar <(E-Mail Removed)> wrote:
> In b1=b2, since you haven't provided an operator =() in class B that
> takes an object of B, you get a default one from compiler which would
> do bitwise copy of B's members.


Not quite. The default operator= does a memberwise copy.
(Otherwise, he wouldn't have seen the message from the operator=
of the base class.) But you're right concerning the important
point here: unless you explicitly declare a "copy assignment"
operator=, the compiler implicitly generates one.

And just for completeness' sake, I'll add that a function
template operator= is never considered "copy assignment", and
will never prevent the compiler from generating its version.

> Since you have provided an operator
> =() in A, the compiler generated operator =() calls this one to copy
> A's members. Hence you see a call to A:perator=().


And if he hadn't provided it, of course, the assignment would
have been illegal.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Casting from base to derived class in base constructor pastbin@gmail.com C++ 2 02-07-2008 02:41 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 01:44 PM
Derived::Derived(const Base&) developereo@hotmail.com C++ 4 05-23-2007 09:32 AM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 12:07 AM
derived class and base class, member assignment, which goes first user C++ 1 07-11-2005 04:25 AM



Advertisments