470,864 Members | 1,989 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,864 developers. It's quick & easy.

operator=


I have a class for which I needed to create an operator= function. I then
use that as a base class for another class, which also needs an operator=.
What is the syntax to use in the derived class operator= function to copy
the base classes variables in the derived class (without just copying the
code?)

A much simplified example:

class Base
{
public:
Base();
~Base();

Base &operator=(const Base &B);

protected:
int i;
}

Base &Base::operator=(const Base &B)
{
if (this == &B)
return *this;
i = B.i;
return *this;
};
class Derived : public Base
{
Derived();
~Derived();

Derived &operator=(const Derived &D);

protected:
int n;
};

Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
return *this;

// None of these work!
//(Base)(*this) = ::operator=B;
//(*this) =(const Base &)B;

n = B.n;
return *this;
};

And yet, in code not directly in these classes, this works fine:
Base b;
Derived d;
d = b;

Thanks!
Corey
Jun 27 '08 #1
17 1397
Hi,

make method "operator=" virtual, this should help. Non-virtual methods
cannot be overwritten, so you will always use operator= from class
Base.

Greetings from Bavaria,
Markus
Jun 27 '08 #2
On Jun 5, 10:09 am, "Corey Cooper" <Co...@EntecSystems.netwrote:
I have a class for which I needed to create an operator= function. I then
use that as a base class for another class, which also needs an operator=.
What is the syntax to use in the derived class operator= function to copy
the base classes variables in the derived class (without just copying the
code?)

A much simplified example:

class Base
{
public:
Base();
~Base();

Base &operator=(const Base &B);

protected:
int i;

}

Base &Base::operator=(const Base &B)
{
if (this == &B)
return *this;
i = B.i;
return *this;

};

class Derived : public Base
{
Derived();
~Derived();

Derived &operator=(const Derived &D);

protected:
int n;

};

Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
return *this;

// None of these work!
//(Base)(*this) = ::operator=B;
//(*this) =(const Base &)B;

n = B.n;
return *this;

};

And yet, in code not directly in these classes, this works fine:
Base b;
Derived d;
d = b;

Thanks!
Corey
Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
return *this;

// None of these work!
//(Base)(*this) = ::operator=B;
//(*this) =(const Base &)B;

n = B.n;
Base::operator =(B);

return *this;
};
Jun 27 '08 #3
On Jun 5, 2:09 am, "Corey Cooper" <Co...@EntecSystems.netwrote:
I have a class for which I needed to create an operator= function. I then
use that as a base class for another class, which also needs an operator=.
What is the syntax to use in the derived class operator= function to copy
the base classes variables in the derived class (without just copying the
code?)
Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
return *this;
You want:

Base::operator = (B);
>
n = B.n;
return *this;

};

That's also the general syntax for calling the base implementation of
a function.

class Base {
virtual void f () { }
};

class Derived : public Base {
void f () {
Base::f();
// ...
}
};
Jason
Jun 27 '08 #4
On Jun 5, 2:32 am, cipher <markus.doerschm...@gmail.comwrote:
make method "operator=" virtual, this should help. Non-virtual methods
cannot be overwritten, so you will always use operator= from class
Base.
That will not help the main problem, though. Also, the derived
operator = takes a Derived&, not a Base&. Virtual or not, if you are
calling operator = on a Base, it will always use the Base one, e.g.:

void assign (Base &a, const Base &b) {
a = b;
}

Will always call Base::operator= only, no matter what derived classes
you pass it. Making operator = virtual in the Base will case
Derived::operator= to be called only if there is a
Derived::operator=(Base&), e.g.:
class Base {
public:
virtual Base & operator = (const Base &); // (1)
};

class Derived {
public:
Derived & operator = (const Derived &); // (2)
Derived & operator = (const Base &); // (3)
};

void assign (Base &a, const Base &b) {
a = b;
}

void f () {
Derived a, b;
a = b; // This calls (2).
assign(a, b); // This calls (3).
}
And assign(a, b) would call (1) if (1) wasn't virtual. But it will
never call (2).
Jason
Jun 27 '08 #5
You want:
>
Base::operator = (B);
>>
n = B.n;
return *this;

};


That's also the general syntax for calling the base implementation of
a function.
Ahh! I forgot that operator= is like any other function, and I kept wanting
to put something on the left of the equals sign!

Thanks All!
<ja************@gmail.comwrote in message
news:f3**********************************@i76g2000 hsf.googlegroups.com...
On Jun 5, 2:09 am, "Corey Cooper" <Co...@EntecSystems.netwrote:
>I have a class for which I needed to create an operator= function. I
then
use that as a base class for another class, which also needs an
operator=.
What is the syntax to use in the derived class operator= function to copy
the base classes variables in the derived class (without just copying the
code?)
> Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
return *this;

You want:

Base::operator = (B);
>>
n = B.n;
return *this;

};


That's also the general syntax for calling the base implementation of
a function.

class Base {
virtual void f () { }
};

class Derived : public Base {
void f () {
Base::f();
// ...
}
};
Jason

Jun 27 '08 #6
On Jun 5, 8:09 am, "Corey Cooper" <Co...@EntecSystems.netwrote:
I have a class for which I needed to create an operator=
function. I then use that as a base class for another class,
which also needs an operator=. What is the syntax to use in
the derived class operator= function to copy the base classes
variables in the derived class (without just copying the
code?)
A much simplified example:
class Base
{
public:
Base();
~Base();
Base &operator=(const Base &B);
protected:
int i;
}
Base &Base::operator=(const Base &B)
{
if (this == &B)
What's this check for? It just wastes time, and is usually a
sign of other problems (but here, it's just unnecessary).
return *this;
i = B.i;
return *this;
};
class Derived : public Base
{
Derived();
~Derived();
Derived &operator=(const Derived &D);
protected:
int n;
};
Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
(As above.)
return *this;
// None of these work!
//(Base)(*this) = ::operator=B;
//(*this) =(const Base &)B;
What's wrong with just:

Base::operator=( B ) ;
n = B.n;
return *this;
};
And yet, in code not directly in these classes, this works fine:
Base b;
Derived d;
d = b;
It does? It shouldn't compile.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #7
On Jun 5, 8:32 am, cipher <markus.doerschm...@gmail.comwrote:
make method "operator=" virtual,
Never make the operator= function virtual. It can't be made to
work correctly.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #8

"James Kanze" <ja*********@gmail.comwrote in message
news:d4**********************************@56g2000h sm.googlegroups.com...
On Jun 5, 8:09 am, "Corey Cooper" <Co...@EntecSystems.netwrote:
I have a class for which I needed to create an operator=
function. I then use that as a base class for another class,
which also needs an operator=. What is the syntax to use in
the derived class operator= function to copy the base classes
variables in the derived class (without just copying the
code?)
A much simplified example:
class Base
{
public:
Base();
~Base();
Base &operator=(const Base &B);
protected:
int i;
}
Base &Base::operator=(const Base &B)
{
if (this == &B)
What's this check for? It just wastes time, and is usually a
sign of other problems (but here, it's just unnecessary).
return *this;
i = B.i;
return *this;
};
class Derived : public Base
{
Derived();
~Derived();
Derived &operator=(const Derived &D);
protected:
int n;
};
Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
(As above.)
return *this;
// None of these work!
//(Base)(*this) = ::operator=B;
//(*this) =(const Base &)B;
What's wrong with just:

Base::operator=( B ) ;
n = B.n;
return *this;
};
>And yet, in code not directly in these classes, this works fine:
Base b;
Derived d;
d = b;
>It does? It shouldn't compile.
VC++ 6.0 it works.
c.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #9
"Corey Cooper" <Co***@EntecSystems.netwrote:
I have a class for which I needed to create an operator= function. I then
use that as a base class for another class, which also needs an operator=.
That sounds like a very bad idea.

void fn(Base& b, Derived& d)
{
b = d;
d = b;
}

AFAIK, in both of the above, Base::op=(const Base&) will be called, but
what if 'b' is a reference to a Derived object?

I don't think the base class should have an op= function. I think the
right thing to do is to make the Base::op= private and not implemented.
Jun 27 '08 #10
On Jun 5, 3:34 pm, "Corey Cooper" <Co...@EntecSystems.netwrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:d4**********************************@56g2000h sm.googlegroups.com...
On Jun 5, 8:09 am, "Corey Cooper" <Co...@EntecSystems.netwrote:
I have a class for which I needed to create an operator=
function. I then use that as a base class for another
class, which also needs an operator=. What is the syntax to
use in the derived class operator= function to copy the base
classes variables in the derived class (without just copying
the code?)
A much simplified example:
class Base
{
public:
Base();
~Base();
Base &operator=(const Base &B);
protected:
int i;
};
[...]
class Derived : public Base
{
Derived();
~Derived();
Derived &operator=(const Derived &D);
protected:
int n;
};
Base b;
Derived d;
d = b;
It does? It shouldn't compile.
VC++ 6.0 it works.
I don't see how. VC++ 6.0 is very old and outdated, but even
then, I don't see what assignment operator it could possibly
use. Are you sure you don't have the assignment backwards:
b = d ;
should work.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #11
On Jun 6, 4:59 am, "Daniel T." <danie...@earthlink.netwrote:
"Corey Cooper" <Co...@EntecSystems.netwrote:
I have a class for which I needed to create an operator=
function. I then use that as a base class for another
class, which also needs an operator=.
That sounds like a very bad idea.
void fn(Base& b, Derived& d)
{
b = d;
d = b;
}
AFAIK, in both of the above, Base::op=(const Base&) will be
called, but what if 'b' is a reference to a Derived object?
As far as I can see, "d = b" is illegal. There is no operator=
in Derived which can be called with a Base.
I don't think the base class should have an op= function. I
think the right thing to do is to make the Base::op= private
and not implemented.
In general, assignment and polymorphism don't work well
together, and in general, assignment should be banned in
polymorphic classes. But the original poster didn't say why he
was deriving; if the motive isn't polymorphism, then it's
possible that providing assignment in both would be justified.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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

Jun 27 '08 #12
On Fri, 06 Jun 2008 02:37:12 -0700, James Kanze wrote:
In general, assignment and polymorphism don't work well together, and in
general, assignment should be banned in polymorphic classes.
That's a bit strong, isn't it? Ok, I don't want to assign an apple to a
pear, even if they're both fruit; but might I at least be allowed to
assign an apple to an apple?

--
Lionel B
Jun 27 '08 #13
LR
Corey Cooper wrote:
I have a class for which I needed to create an operator= function. I then
use that as a base class for another class, which also needs an operator=.
What is the syntax to use in the derived class operator= function to copy
the base classes variables in the derived class (without just copying the
code?)

A much simplified example:

class Base
{
public:
Base();
~Base();

Base &operator=(const Base &B);

protected:
int i;
}
;
>
Base &Base::operator=(const Base &B)
{
if (this == &B)
return *this;
i = B.i;
return *this;
};
class Derived : public Base
{
Derived();
~Derived();

Derived &operator=(const Derived &D);

protected:
int n;
};

Derived &Derived::operator=(const Derived &B)
{
if (this == &B)
return *this;

// None of these work!
//(Base)(*this) = ::operator=B;
//(*this) =(const Base &)B;

n = B.n;
return *this;
};

And yet, in code not directly in these classes, this works fine:
Base b;
Derived d;
d = b;
I don't see how. Derived's default ctor is private above. I suspect
that you didn't cut and paste when you posted. It adds a little bit of
confusion.

I also think that assigning a base instance to a derived instance is
rather ugly. Can be done, but I'm curious as to why you want to.
Perhaps better IMHO to create a ctor for the derived class like
Derived(const Base &b, const int v) : Base(b), n(v) {}

Please consider the following code, and also, please see
http://www.gotw.ca/gotw/059.htm
NB, I've assumed that you did in fact want Derived(), ~Derived() and
Derived &operator=(const Derived &d) to be public.

class Base
{
static int testValue() { return -99; }
public:
void swap(Base &b) {
std::swap(b.i,i);
}
Base() : i(testValue()) {}
Base(const int v) : i(v) {} // just for testing
Base(const Base &b) : i(b.i) {}
virtual ~Base() {} // virtual

Base &operator=(const Base &B);

protected:
int i;
};

Base &Base::operator=(const Base &b)
{
Base temp(b);
swap(temp);
return *this;
}
class Derived : public Base
{
static int testValueA() { return -55; }
static int testValueB() { return -52; }
public: // So the code you provided to exercise these can compile
void swap(Derived &d) {
Base::swap(d);
std::swap(d.n,n);
}
Derived() : Base(), n(testValueA()) {}
Derived(const Derived &d) : Base(d), n(d.n) {}

Derived(const Base &b, const int v) : Base(b), n(v) {}

// a ctor like this might not be the best thing to do.
Derived(const Base &b) : Base(b), n(testValueB()) {}
~Derived() {}

Derived &operator=(const Derived &d);
Derived &operator=(const Base &b);

protected:
int n;
};

Derived &Derived::operator=(const Derived &d)
{
Derived temp(d);
swap(temp);
return *this;
}
Derived &Derived::operator=(const Base &b) {
// This seems rather ugly to me.
// NB that we're not preserving
// what's on the left hand side of the =
// we use to call this.
// We could play games to do that
// if that's what you want, but I tend to think
// that you'd be better off using some other syntax
// for that.
Derived temp(b);
swap(temp);
return *this;
}

int main() {
Base b(44); // changed for testing
Derived d;
d = b; // Why? What?
d = Derived(b,67); // might be better IMHO
}

I'm not clear on what you want to do. I think that someone reading your
code, maybe even you, might have to pause over d=b; What does that do?

If you want d=b to result in a change to d.i but not d.n then perhaps
you ought to consider a ctor like,

Derived(const Base &b, const Derived &d) : Base(b), n(d.n) {}

and then write
d = Derived(b,d);

which I think will communicate your intent a little better than an
unusual Derived &operator=(const Base &) ever could. IMO.

But this sort of stuff doesn't seem pretty to me, so I'd like to know,
why do you want to do this?

LR

Jun 27 '08 #14
Hi!

James Kanze schrieb:
>AFAIK, in both of the above, Base::op=(const Base&) will be
called, but what if 'b' is a reference to a Derived object?

As far as I can see, "d = b" is illegal. There is no operator=
in Derived which can be called with a Base.
Only because the derived operator = hides the one of the base class.
This is a good thing because it makes "d = b" fail.
In general, assignment and polymorphism don't work well
together, and in general, assignment should be banned in
polymorphic classes. But the original poster didn't say why he
was deriving; if the motive isn't polymorphism, then it's
possible that providing assignment in both would be justified.
In which case the op = could safely be protected and be called from
derived classes.

Frank
Jun 27 '08 #15
On Jun 6, 12:18 pm, Lionel B <m...@privacy.netwrote:
On Fri, 06 Jun 2008 02:37:12 -0700, James Kanze wrote:
In general, assignment and polymorphism don't work well
together, and in general, assignment should be banned in
polymorphic classes.
That's a bit strong, isn't it? Ok, I don't want to assign an
apple to a pear, even if they're both fruit; but might I at
least be allowed to assign an apple to an apple?
In which case, presumably, the client code will be dealing with
apples, there's no polymorphism, and no problem. There's no
fundamental problem with providing assignment in the most
derived class, but there's usually also no real use for it,
since the whole point of having a hierarchy is that the client
code deals only with pointers and references to the base class.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #16
Frank Birbacher <bl************@gmx.netwrote:
James Kanze schrieb:
In general, assignment and polymorphism don't work well
together, and in general, assignment should be banned in
polymorphic classes. But the original poster didn't say why he
was deriving; if the motive isn't polymorphism, then it's
possible that providing assignment in both would be justified.

In which case the op = could safely be protected and be called from
derived classes.
Better would be to make a protected, named member-function and keep the
op= private and undefined.
Jun 27 '08 #17
Hi!

Daniel T. schrieb:
Better would be to make a protected, named member-function and keep the
op= private and undefined.
Even better, agreed.

Frank
Jun 27 '08 #18

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by joesoap | last post: by
reply views Thread by Martin Magnusson | last post: by
3 posts views Thread by Sensei | last post: by
6 posts views Thread by YUY0x7 | last post: by
3 posts views Thread by gugdias | last post: by
8 posts views Thread by valerij | last post: by
3 posts views Thread by y-man | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.