operator+ in derived classes

J

Jim Langston

This is something someone was asking in irc. I really don't need to do this
right now, but may have to in the future. The following code is in error
(marked).

#include <iostream>
#include <string>

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) { Base Temp( x_ ); Temp.x_ += b.x_;
return Temp; }
int X() { return x_; }
virtual ~Base() {}
private:
int x_;
};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
int Y() { return y_; }
private:
int y_;
};

int main()
{

Base MyBase(10);
std::cout << MyBase.X() << "\n";

Base MyBase2 = MyBase + Base(5);
std::cout << MyBase2.X() << "\n";


Derived MyDerived( 10, 20 );
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
// Following line gives compilation error
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";
// error C2440: 'initializing' : cannot convert from 'Base' to 'Derived'
// No constructor could take the source type, or constructor
overload resolution was ambiguous

std::string wait;
std::getline( std::cin, wait );

}

I understand the error. I am tryign to operator+ on derived, but the only
operator + is on base.

How do people handle this?

What would be a nice solution, if possible, is to have a derived operator+
that calls the base operator+ for the addition of the x_'s, then add the
y_'s in derived operator+ and return derived. I couldn't come up with a way
to do this however, and think I would have to totally rewrite the operator+
for derived. In this case it's trivial, but I could see a complex class
where it wouldn't be so trivial.

Any thoughts?
 
J

Jim Langston

Jim Langston said:
This is something someone was asking in irc. I really don't need to do
this right now, but may have to in the future. The following code is in
error (marked).

#include <iostream>
#include <string>

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) { Base Temp( x_ ); Temp.x_ += b.x_;
return Temp; }
int X() { return x_; }
virtual ~Base() {}
private:
int x_;
};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
int Y() { return y_; }
private:
int y_;
};

int main()
{

Base MyBase(10);
std::cout << MyBase.X() << "\n";

Base MyBase2 = MyBase + Base(5);
std::cout << MyBase2.X() << "\n";


Derived MyDerived( 10, 20 );
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";

My bad, the following line is the one in error, not the one below it. It's
the operator+ that's causing the problem, not the X() and Y();

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
// error C2440: 'initializing' : cannot convert from 'Base' to 'Derived'
// No constructor could take the source type, or constructor
 
V

Victor Bazarov

Add here

Derived(const Base& b) : Base(b), y_(0) {}
My bad, the following line is the one in error, not the one below it.
It's the operator+ that's causing the problem, not the X() and Y();

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
// error C2440: 'initializing' : cannot convert from 'Base' to
'Derived' // No constructor could take the source type, or
constructor

Add the constructor from Base.
 
J

Jim Langston

Victor Bazarov said:
Add here

Derived(const Base& b) : Base(b), y_(0) {}


Add the constructor from Base.

That semi works. I.E. After fixing typos (actually displaying MyDerived2
values) my output is:
10
15
10 20
15 0

When I would want output of:
10
15
10 20
15 30

So I'm thinking I'm going to need to add y_ to y_ in derived. I tried to
add an operator+ to Derived with no success in getting what I want.

Derived operator+( const Derived& d ) { Derived Temp( X(), y_ ); Temp.y_ +=
d.y_; return Temp; }

Output is now
10
15
10 20
10 30

So it seems I can either add the base variables, or the derived variables,
but not both. I tried this but can't get it to compile

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) { Base Temp( x_ ); Temp.x_ += b.x_;
return Temp; }
int X() { return x_; }
virtual ~Base() {}
private:
int x_;
};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
Derived operator+( const Derived& d )
{
// Error on following line
Base TempBase = Base( this->X() ) + Base( d.X() );
// error C2662: 'Base::X' : cannot convert 'this' pointer from
'const Derived' to 'Base &'


Derived Temp( TempBase.X(), y_ );
Temp.y_ += d.y_;
return Temp;
}
int Y() { return y_; }
private:
int y_;
};

I can't figure out why I'm getting that error. It seems I can't get d.X().
I tried int TempInt = d.X() with the same error. I know outside the class
in mainline I can get a derived.X(); why cant' I in the operator+?
 
C

c++ seeker

This is something someone was asking in irc. I really don't need to do this
right now, but may have to in the future. The following code is in error
(marked).

#include <iostream>
#include <string>

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) { Base Temp( x_ ); Temp.x_ += b.x_;
return Temp; }
int X() { return x_; }
virtual ~Base() {}
private:
int x_;

};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
int Y() { return y_; }
private:
int y_;

};

int main()
{

Base MyBase(10);
std::cout << MyBase.X() << "\n";

Base MyBase2 = MyBase + Base(5);
std::cout << MyBase2.X() << "\n";

Derived MyDerived( 10, 20 );
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
// Following line gives compilation error
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";
// error C2440: 'initializing' : cannot convert from 'Base' to 'Derived'
// No constructor could take the source type, or constructor
overload resolution was ambiguous

std::string wait;
std::getline( std::cin, wait );

}

I understand the error. I am tryign to operator+ on derived, but the only
operator + is on base.

How do people handle this?

What would be a nice solution, if possible, is to have a derived operator+
that calls the base operator+ for the addition of the x_'s, then add the
y_'s in derived operator+ and return derived. I couldn't come up with a way
to do this however, and think I would have to totally rewrite the operator+
for derived. In this case it's trivial, but I could see a complex class
where it wouldn't be so trivial.

Any thoughts?

Derived& operator+(const Derived &d){
this->Base::eek:perator+(d);
this->y_ += d.y_;
return *this;
}
 
J

Jim Langston

Jim Langston said:
That semi works. I.E. After fixing typos (actually displaying MyDerived2
values) my output is:
10
15
10 20
15 0

When I would want output of:
10
15
10 20
15 30
<Snipped trial and error til I got it right>

This is what I wound up donig. Is this the way you would necessarily do it?

#include <iostream>
#include <string>

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) const { Base Temp( x_ ); Temp.x_ += b.x_;
return Temp; }
int X() const { return x_; }
virtual ~Base() {}
private:
int x_;
};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
Derived operator+( const Derived& d ) const
{
Base TempBase = Base( this->X() ) + Base( d.X() );
Derived Temp( TempBase.X(), y_ );
Temp.y_ += d.y_;
return Temp;
}
int Y() const { return y_; }
private:
int y_;
};

int main()
{

Base MyBase(10);
std::cout << MyBase.X() << "\n";

Base MyBase2 = MyBase + Base(5);
std::cout << MyBase2.X() << "\n";

Derived MyDerived( 10, 20 );
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
std::cout << MyDerived2.X() << " " << MyDerived2.Y() << "\n";

std::string wait;
std::getline( std::cin, wait );

}

Output is my wanted:
10
15
10 20
15 30
 
J

Jim Langston

This is something someone was asking in irc. I really don't need to do
this
right now, but may have to in the future. The following code is in error
(marked).

#include <iostream>
#include <string>

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) { Base Temp( x_ ); Temp.x_ += b.x_;
return Temp; }
int X() { return x_; }
virtual ~Base() {}
private:
int x_;

};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
int Y() { return y_; }
private:
int y_;

};

int main()
{

Base MyBase(10);
std::cout << MyBase.X() << "\n";

Base MyBase2 = MyBase + Base(5);
std::cout << MyBase2.X() << "\n";

Derived MyDerived( 10, 20 );
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
// Following line gives compilation error
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";
// error C2440: 'initializing' : cannot convert from 'Base' to
'Derived'
// No constructor could take the source type, or constructor
overload resolution was ambiguous

std::string wait;
std::getline( std::cin, wait );

}

I understand the error. I am tryign to operator+ on derived, but the only
operator + is on base.

How do people handle this?

What would be a nice solution, if possible, is to have a derived operator+
that calls the base operator+ for the addition of the x_'s, then add the
y_'s in derived operator+ and return derived. I couldn't come up with a
way
to do this however, and think I would have to totally rewrite the
operator+
for derived. In this case it's trivial, but I could see a complex class
where it wouldn't be so trivial.

Any thoughts?

Derived& operator+(const Derived &d){
this->Base::eek:perator+(d);
this->y_ += d.y_;
return *this;
}

Output of that is:
10
15
10 20
10 30

Instead of
10
15
10 20
15 30

Also, it changes this, but += is not what I wanted.
 
V

Victor Bazarov

Jim said:
<Snipped trial and error til I got it right>

This is what I wound up donig. Is this the way you would necessarily
do it?
#include <iostream>
#include <string>

class Base
{
public:
Base( const int x = 0): x_( x ) {}
Base operator+( const Base b ) const { Base Temp( x_ ); Temp.x_ +=
b.x_; return Temp; }

It should really be shorter:

Base operator+(const Base& b) const { return Base(b.x_ + x_); }
int X() const { return x_; }
virtual ~Base() {}
private:
int x_;
};

class Derived: public Base
{
public:
Derived( const int x = 0, const int y = 0): Base( x ), y_( y ) {}
Derived operator+( const Derived& d ) const
{
Base TempBase = Base( this->X() ) + Base( d.X() );
Derived Temp( TempBase.X(), y_ );
Temp.y_ += d.y_;
return Temp;
}

Yep, something like that. You don't really need to construct new Base
objects from X(). You could just cast '*this' and 'd' to Base&:

Derived operator+( const Derived& d ) const
{
Base TempBase(Base(*this) + Base(d)); // fall back on Base::eek:p+
return Derived( TempBase.X(), y_ + d_.y );

}
int Y() const { return y_; }
private:
int y_;
};

int main()
{

Base MyBase(10);
std::cout << MyBase.X() << "\n";

Base MyBase2 = MyBase + Base(5);
std::cout << MyBase2.X() << "\n";

Derived MyDerived( 10, 20 );
std::cout << MyDerived.X() << " " << MyDerived.Y() << "\n";

Derived MyDerived2 = MyDerived + Derived( 5, 10 );
std::cout << MyDerived2.X() << " " << MyDerived2.Y() << "\n";

std::string wait;
std::getline( std::cin, wait );

}

Output is my wanted:
10
15
10 20
15 30

See above. I don't know the output -- no time to try, and too lazy
to just look and figure it out. However, it might not be what you
want. Generally, you do want to fall back on Base::eek:perator+ as
much as possible instead of adding 'x_' values yourself. For that
you might want to make operator+ virtual...

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top