Overloading the + Operator in a Derived Class

Greetings

I have a class called Date and another called DateTime that is derived from Date. The class Date has a provision to overload the + operator. I am trying to overload the + operator in the DateTime class as well.

Now, according to me, the overloading of the + operator in the DateTime class should overload the + operator in the Date class, right? But when I try to do it, it is throwing me an error: "DateTime DateTime::operator+(int) cannot be overloaded."

My question is... why?
the overloading of the + operator in the DateTime class should overload the + operator in the Date class


Try overloading the operator in the base class, not the derived class.

Edit: Post some code - with code tags, then we can see what's happening.

Edit2: I need to learn to read properly - you already have it in the base class. Lets see the code.
Last edited on
Thanks for the quick response.

The Date class has the members: dd, mm, yy.
DateTime has the additional members: hh, min.

Here's the code to overload the + operator in the base class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Date Date::operator+(int extradays){
	Date temp;	
	int rem;
	temp.dd=dd+extradays;
	switch(mm){
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:if(temp.dd>31){
					temp.dd=temp.dd%31;
					temp.mm=mm+1;
					}
				break;
		case 12: if(temp.dd>31){
					temp.dd=temp.dd%31;
					temp.mm=1;
					temp.yy++;
					}
				break;
		case 4:
		case 6:
		case 9:
		case 11:if(temp.dd>30){
					temp.dd=temp.dd%30;
					temp.mm=mm+1;
					}
			break;
		case 2: if(yy%4==0)
				if(temp.dd>29){
					temp.dd=temp.dd%29;
					temp.mm=mm+1;
					}
				else if(temp.dd>28){
					temp.dd=temp.dd%28;
					temp.mm=mm+1;
					}
		}
return temp;
}

So for something like:
Date d;
d=d+3;
3 days will be added to the date.

And here's the code to overload the + operator in the derived class:
1
2
3
4
5
6
7
8
DateTime DateTime::operator+(int extramin){
	int temp;
	temp=min+extramin;
	if(temp>59)
		hh++;
	min=temp%60;
	return *this;
}

For something like:
DateTime dt;
dt=dt+3;
3 minutes will be added to the time.
Something like this (basically yours shortened with more overloads) works fine for me:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class A
{
public:
	A operator+(A rhs)
	{
		this->i += rhs.i;
		return *this;
	}
	A operator+(int rhs)
	{
		this->i += rhs;
		return *this;
	}
private:
	int i;
};

class B: public A
{
public:
	B operator+(B rhs)
	{
		this->d += rhs.d;
		return *this;
	}
	B operator+(int rhs)
	{
		this->d += rhs;
		return *this;
	}
private:
	int d;
};


Also, your code has a bug:
1
2
3
if(temp>59)
	hh++; //What if a user passes 300 minutes?
min=temp%60;


I'd just use a while loop, and subtract the 60 minutes every iteration. You'll also need to watch changes in day, month and so on.
Is it that you want to override operator+ instead of overloading it?

Overloaded functions have the same name but different arguments.

Overridden functions have the same name and the same arguments, but they have different definitions in the base class and the derived class.

the overloading of the + operator in the DateTime class should overload the + operator in the Date class

The derived class is affected by the base class and the base class is independent of the derived class. You can think of inheritance as copying all non-private functions from the base class and pasting them in the derived class. The derived class will then 'inherit' functions of the base class (which can be overridden) but there will be no change in the base class. Then you can add some member functions and data members of your own to the derived class otherwise it will be almost an exact copy of the base class. These members will not affect the base class.

I don't know what the error message means as I haven't seen the code. So please post code.
Last edited on
@BlackSheep: Didn't think of that :) Thanks

@Eklavya: I made a mistake in my original post. I meant that shouldn't the derived class' overloaded operator be called instead of the base class' one when manipulating an object that belongs to the derived class?

I've put up some code in my second post.
It does call the derived operator. Try this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>

class A
{
public:
	A operator+(int rhs)
	{
		this->i += rhs;
		std::cout<<"A+"<<std::endl;
		return *this;
	}
private:
	int i;
};

class B: public A
{
public:
	B operator+(int rhs)
	{
		this->d += rhs;
		std::cout<<"B+"<<std::endl;
		return *this;
	}
private:
	int d;
};

int main()
{
B b;
b = b + 1;
A a;
a = a + 1;
std::getchar();
return 0;
}


EDIT: Yes, there should be some more consts in there, but I'm lazy.
Last edited on
What errors do you get?

I'd suggest not to inherit DateTime form Date. Instead use Date as a member variable. Hiding members is not a good idea
^Um, all that prints is:
B+
A+


To clarify, derived class operators do not automatically call base class operators; you must call them yourself.
Which is what I expected it to print. Peter had a problem which for some reason would not allow him to define the operator+ for his derived class, and I simplified his code to get to the root of the problem.
> I meant that shouldn't the derived class' overloaded operator be called instead of the base class' one
> when manipulating an object that belongs to the derived class?

For that, the overloaded operator has to be a virtual function that is overridden in a derived class. This is fine for operator+= which returns a reference, but problematic for operator+ which returns a value.

In general, run-time polymorphism, static typing and value semantics don't mix well - you will have to let go of at least one of them. It has been a perennial problem in languages like C++ and Java that have kludged run-time polymorphism on top of C.

You could try something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <type_traits>

struct base
{
    virtual ~base() {}
    virtual base& operator+= ( int v )
    { std::cout << "base::operator+=(int)\n" ; return *this ; }
    base plus( int v ) const
    { std::cout << "base::operator+(int)\n" ; base temp(*this) ; return temp+=v ; }
};

template< typename T > typename std::enable_if< std::is_base_of<base,T>::value, T >::type
operator+ ( const T& t, int i ) { return t.plus(i) ; }

template< typename T > typename std::enable_if< std::is_base_of<base,T>::value, T >::type
operator+ ( int i, const T& t ) { return t.plus(i) ; }

struct derived : base
{
    virtual derived& operator+= ( int v ) override // co-variant return type
    { std::cout << "*** derived::operator+=(int)\n" ; return *this ; }
    derived plus( int v ) const
    { std::cout << "*** derived::operator+(int)\n" ; derived temp(*this) ; return temp+=v ; }
};

int main()
{
    base b ;
    derived d ;
    base& b1 = b ;

    b += 5 ; std::cout << '\n' ;
    b1 += 5 ; // ok, polymorphic
    d += 5 ; std::cout << '\n' ;

    auto x = b + 5 ; std::cout << '\n' ; // fine
    auto y = d + 5 ; std::cout << '\n' ;
    x = 5 + b ; std::cout << '\n' ;
    y = 5 + d ; std::cout << '\n' ;

    auto z = b1 + 5 ; // ?????
}
It works! It was such a stupid mistake that I had made and it only came to my attention after playing a bit of Slender. I had declared the + operator overloading function twice in the same class.
Moral: When stuck, take a break and try again with a fresh mindset.

Many thanks for all your help though.

@BlackSheep: You've saved me a lot of embarrassment by catching that bug.
@JLBorges: I found your last post to be very helpful.
Topic archived. No new replies allowed.