Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Virtual Assignment Operator in Protocol class

Reply
Thread Tools

Virtual Assignment Operator in Protocol class

 
 
N4M
Guest
Posts: n/a
 
      08-17-2004
Dear,
Suppose I have a Protocol class, in which I need also an assignment
operator =().
class B
{
.....
virtual B& operator=(const B& rb) =0;
};
Now in some derived class D: public B, how would I proceed with
operator=? Do I need to supply 2 operators:
-01 to override D& operator=(const B& d)
-and 01 to overload D& operator=(const D& d)?
How about the (im)purality of = ?
Thanks for your guidance.
 
Reply With Quote
 
 
 
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      08-17-2004
N4M wrote:
>
> Dear,
> Suppose I have a Protocol class, in which I need also an assignment
> operator =().
> class B
> {
> ....
> virtual B& operator=(const B& rb) =0;
> };
> Now in some derived class D: public B, how would I proceed with
> operator=? Do I need to supply 2 operators:
> -01 to override D& operator=(const B& d)
> -and 01 to overload D& operator=(const D& d)?
> How about the (im)purality of = ?
> Thanks for your guidance.


In a nutshell: having op= as virtual is seldome a good idea. Mostly
because it doesn't work how most people would expect it to work.
Hint: polymorphism works only by examining the object the function
is called for, but doesn't take the runtime type of the arguments
into account.

Assume class D, derived from class B

B* p1 = new D;
B* p2 = new D;

*p1 = *p2;

In the above, what do you think the compiler is looking for
when searching a function to fullfil the request of the
assignment? :

1) B:perator=( const B& Arg );
or 2) B:perator=( const D& Arg );
or 3) D:perator=( const B& Arg );
or 4) D:perator=( const D& Arg );

--
Karl Heinz Buchegger
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      08-17-2004
Karl Heinz Buchegger wrote:
>
> N4M wrote:
> >
> > Dear,
> > Suppose I have a Protocol class, in which I need also an assignment
> > operator =().
> > class B
> > {
> > ....
> > virtual B& operator=(const B& rb) =0;
> > };
> > Now in some derived class D: public B, how would I proceed with
> > operator=? Do I need to supply 2 operators:
> > -01 to override D& operator=(const B& d)
> > -and 01 to overload D& operator=(const D& d)?
> > How about the (im)purality of = ?
> > Thanks for your guidance.

>
> In a nutshell: having op= as virtual is seldome a good idea. Mostly
> because it doesn't work how most people would expect it to work.
> Hint: polymorphism works only by examining the object the function
> is called for, but doesn't take the runtime type of the arguments
> into account.


After rethinking (and smoking a cigarette) I don't think this to be
relevant any more. Read on ...

>
> Assume class D, derived from class B
>
> B* p1 = new D;
> B* p2 = new D;
>
> *p1 = *p2;
>
> In the above, what do you think the compiler is looking for
> when searching a function to fullfil the request of the
> assignment? :
>
> 1) B:perator=( const B& Arg );
> or 2) B:perator=( const D& Arg );
> or 3) D:perator=( const B& Arg );
> or 4) D:perator=( const D& Arg );
>


Next thought experiment (you might want to try this with your compiler
anyway): make the operator virtual.
Which op= is called then?

Hint: Think about what a dereference operation does when the runtime
type of an object differs from the static type of the pointer pointing
to it.

--
Karl Heinz Buchegger
(E-Mail Removed)
 
Reply With Quote
 
Risto Lankinen
Guest
Posts: n/a
 
      08-17-2004

"Karl Heinz Buchegger" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> In a nutshell: having op= as virtual is seldome a good idea. Mostly
> because it doesn't work how most people would expect it to work.
> Hint: polymorphism works only by examining the object the function
> is called for, but doesn't take the runtime type of the arguments
> into account.


Then programmer must do that, no?

> Assume class D, derived from class B
>
> B* p1 = new D;
> B* p2 = new D;
>
> *p1 = *p2;
>
> In the above, what do you think the compiler is looking for
> when searching a function to fullfil the request of the
> assignment? :
>
> 1) B:perator=( const B& Arg );
> or 2) B:perator=( const D& Arg );
> or 3) D:perator=( const B& Arg );
> or 4) D:perator=( const D& Arg );


The symptoms you demonstrate do not exist (nor become better
or worse) because of virtual assignment, but because of how
C++ object model works. In real world, virtual assignment is not
the disease, but the cure!

Consider this example:

// ========================================

struct B
{
// this is a pretty canonical class, except for virtual assignment

virtual B &operator=( const B & );

// virtual destructor needed for derived deletion thru base *

virtual ~B();

// add more members (data or functions) to suit the taste...
};


struct D : public B
{
int value;

D( int i=0 ) : value(i)
{
}

D( const D &r ) : B(r) , value(r.value)
{
}

virtual D &operator=( const D &r )
{
B:perator=( r );
value = r.value;
return *this;
}

virtual B &operator=( const B &r )
{
const D *p = dynamic_cast<const D *>(&r);

if( p )
{
*this = *p;
}
else
{
// D is being sliced, but now you can detect and compensate!!!
B:perator=( r );
value = 0;
}

return *this;
}
};

// ========================================

Now your example...

> B* p1 = new D;
> B* p2 = new D;
>
> *p1 = *p2;


.... will assign as-if using the most intuitive choice...

> 1) B:perator=( const B& Arg );
> or 2) B:perator=( const D& Arg );
> or 3) D:perator=( const B& Arg );
> or 4) D:perator=( const D& Arg );


.... which, of course, is 4 .

- Risto -


 
Reply With Quote
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      08-17-2004
Risto Lankinen wrote:
>
>
> ... which, of course, is 4 .
>
> - Risto -


Thanks for bringing me back on track.
I don't know why, but somehow I always get lost when
thinking about a virtual op=


--
Karl Heinz Buchegger
(E-Mail Removed)
 
Reply With Quote
 
N4M
Guest
Posts: n/a
 
      08-17-2004
"Risto Lankinen" <(E-Mail Removed)> wrote in message news:<fEnUc.22991$(E-Mail Removed)>...
> "Karl Heinz Buchegger" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> >

Thanks for your example, but what if it is insisted to have all
operators and functions in the ABC be PURE ? Then I cannot initiate B
b...
That's driving my crazy.
N4M
 
Reply With Quote
 
N4M
Guest
Posts: n/a
 
      08-17-2004
"Risto Lankinen" <(E-Mail Removed)> wrote in message news:<fEnUc.22991$(E-Mail Removed)>...
> "Karl Heinz Buchegger" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> >

Thanks for your example, but what if it is insisted to have all
operators and functions in the ABC be PURE ? Then I cannot initiate B
b...
That's driving my crazy.
N4M
 
Reply With Quote
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      08-18-2004
N4M wrote:
>
> "Risto Lankinen" <(E-Mail Removed)> wrote in message news:<fEnUc.22991$(E-Mail Removed)>...
> > "Karl Heinz Buchegger" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed)...
> > >

> Thanks for your example, but what if it is insisted to have all
> operators and functions in the ABC be PURE ? Then I cannot initiate B
> b...
> That's driving my crazy.


I don't understand.

Making those functions PURE (by adding = 0), doesn't mean that
you cannot provide an implementation for them

--
Karl Heinz Buchegger
(E-Mail Removed)
 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      08-18-2004
(E-Mail Removed) (N4M) wrote:

> Dear,
> Suppose I have a Protocol class, in which I need also an assignment
> operator =().
> class B
> {
> ....
> virtual B& operator=(const B& rb) =0;
> };
> Now in some derived class D: public B, how would I proceed with
> operator=?


Let's consider this tree:

class B {
public:
virtual ~B() { }
virtual B& operator=( const B& ) = 0;
};

class D {
int foo;
public:
virtual B& operator=( const B& );
};

class C {
double bar;
public:
virtual B& operator=( const B& );
};

Can either D:p= or C:p= be implemented reasonably? I don't think so.
What is supposed to happen with this code?

void fun( B& b1, B& b2 ) {
b1 = b2;
}

If b1 is an D and b2 is a C?


> Do I need to supply 2 operators:
> -01 to override D& operator=(const B& d)


You need to provide this one.

> -and 01 to overload D& operator=(const D& d)?


You would only need this one if something in the class requires it,
otherwise it will be created properly for you.

The moral of the story here is "don't provide a pure virtual op=".
 
Reply With Quote
 
Risto Lankinen
Guest
Posts: n/a
 
      08-18-2004

"Daniel T." <(E-Mail Removed)> wrote in message newsostmaster->
> Let's consider this tree:
>
> class B {
> public:
> virtual ~B() { }
> virtual B& operator=( const B& ) = 0;
> };
>
> class D {
> int foo;
> public:
> virtual B& operator=( const B& );
> };
>
> class C {
> double bar;
> public:
> virtual B& operator=( const B& );
> };
>
> Can either D:p= or C:p= be implemented reasonably?


Absolutely. Here's one way:

B &D:perator=( const B &r )
{
const D *p = dynamic_cast<const D *>(&r);
if( p )
foo = p->foo;
else
throw "Silly assignment!";
return *this;
}

B &C:perator=( const B &r )
{
const C *p = dynamic_cast<const C *>(&r);
if( p )
bar = p->bar;
else
throw "Silly assignment!";
return *this;
}

> What is supposed to happen with this code?
>
> void fun( B& b1, B& b2 ) {
> b1 = b2;
> }
>
> If b1 is an D and b2 is a C?


With virtual assignment, it would throw a "Silly assignment!"
exception (or alternatively, whatever else the author of the
class D deems appropriate for the case when, so to speak,
an Orange is assigned to a Banana thru a reference to Fruit).

WithOUT virtual assignment it would create a banana the size
of a grape, with an orange skin that doesn't need to be peeled
before eating.

> The moral of the story here is "don't provide a pure virtual op=".


This belief, I think, needs reconsideration.

- Risto -


 
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
POD and assignment operator and test operator Hicham Mouline C++ 2 09-01-2009 06:00 PM
conditions for automatic generation of default ctor, copy ctor,and default assignment operator (operator) puzzlecracker C++ 8 04-15-2008 09:56 PM
Assignment operator self-assignment check Chris C++ 34 09-26-2006 04:26 AM
comma operator and assignment operator G Patel C Programming 4 02-08-2005 02:53 AM
virtual assignment operator/polymorphism question Stephan Kurpjuweit C++ 3 06-14-2004 06:19 PM



Advertisments