Subtracting two objects (overloading -)

Im having a bit of an issue subtracting two objects, the following code runs however it crashes after outputting the two objects. Ive ran into a wall at this point all help is greatly appreciated! Thanks. (Side note: this is a test review , not homework/project)

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  #include <iostream>

using namespace std;


template<class T>
class Box
{
private:
    T length;
    T width;
    T height;
public:
    Box(T l, T w, T h)
    {
        length = l;
        width = w;
        height = h;
    }

    T getLength()
    {
        return length;
    }
    T getWidth()
    {
        return width;
    }
    T getHeight()
    {
        return height;
    }
    void swapval()
    {
        T ar[3];
        ar[0] = length;
        ar[1] = width;
        ar[2] = height;
        cout << "Before swap: ";
        for(int i =0; i < 3; i++)
        {
            cout << ar[i] << " ";
        }
        T temp;
        temp = ar[0];
        ar[0] = ar[2];
        ar[2] = temp;
        temp = ar[1];
        ar[1] = ar[2];
        ar[2] = temp;
        cout << endl;
        cout << "After swap: ";
        for(int j=0; j < 3; j++)
        {

            cout << ar[j] <<" ";
        }
        cout << endl;
    }
     friend ostream& operator<<(ostream& os, Box& b)
     {
         os << "(" << b.length << "," << b.width << "," << b.height << ")" << endl;
         return os;
     }
      friend Box operator-(Box& c, const Box& d)
      {
          c - d;
          return c;
      }
    ~Box()
    {

    }

};


int main()
{
    Box<int> box1(21, 34, 1);
    cout << "Box 1:" << box1;
    Box<int> box2(1, 1, 1);
    cout << "Box 2:" << box2;
    box1 - box2;


    return 0;
}
There's a problem about the concept of subtracting a box from a box (which is a rectangle subtracted from a rectangle), but first I'll address the lexical issues here.

 
 box1 - box2;


Imagine if I state this:

1
2
3
4
5
int a = 5;
int b = 6;

b - a;


What happens in the subtraction of b - a? It goes nowhere. It's lost. The subtraction has no meaning because nothing is happening with it. It isn't being printed, nor passed to a function, or stored in a result.

Now, consider:


1
2
3
4
5
int a = 5;
int b = 6;

int c = b - a;


Here at least c stores the result of the subtraction, but there's an important point I think escapes you. Nothing is done to b. It's value does not change. Similarly, the value of a is unaltered. The subtraction is performed as a temporary, and that temporary result is stored in c. Subtraction of anything works along those basic lines, even objects created from classes.

So:

 
 box1 - box2;


Does nothing for similar reasons. It is important to note that nothing should happen to the values of box1 or box2, but if I assumed there's a box3 which accepted the answer (and there's reason to question what that might be), only box3 would contain the result.

I stress this because of this from you post:

1
2
3
4
5
      friend Box operator-(Box& c, const Box& d)
      {
          c - d;
          return c;
      }


Here you return c, but the subtraction of c - d does nothing TO c. The subtraction would be lost, and the same c passed in would be returned.

You could return c - d, if the subtraction can be performed.

Now that leads me to ask what you expect to be the result.

Whenever a rectangle is to be subtracted from a rectangle, the result is not a simple mathematical operation. It is not like subtracting a vector2d from a vector2d, which merely moves a vector. Subtracting a rectangle from a rectangle may not produce a rectangle as the result. This is true of 3D and 2D, so I'll describe this in 2D for simplicity.

First, from a conceptual viewpoint, the subtraction of a rectangle from any shape requires that the two shapes overlap somehow. If they don't, the result depends on how you prefer to interpret the subtraction, but the usual answer is that the original rectangle is unchanged.

If you imagine a small rectangle entirely inside a large rectangle, subtraction would cut a hole in the larger rectangle, creating a much more complicated shape with more points to describe the shape.

If you subtracted a large rectangle from a small rectangle, and the large rectangle completely surrounded the small rectangle, you'd expect the result to be nothing. That's because the large rectangle would completely consume the small rectangle it completely enveloped.

There is an entire branch of math/logic that deals with this kind of work, but it isn't simple. There are a number of "edge cases" - indeed, the very name "edge case" comes from the kind of thing that you witness when you notice how edges of these shapes might touch but not overlap.

So, I doubt you CAN subtract a rectangle from a rectangle with a simple concept.

Even if you did, did you notice that the friend operator does not mention anything about the members of box (length, width, height)?

What you CAN do in simple terms, however, is to scale (shrink or expand), or move (relocate). Unfortunately the information in the class box does not include the notion of a location. It is just the dimensions, but not the location. So for this kind of box, it could be scaled but not moved.

To scale, you would simply multiply the dimensions by some single number (likely a float or double). That's an operator you could make with simple math and uncomplicated logic.

If you're going to move the rectangle, you need a location.

Let's say you want to scale the rectangle such that this could be made a valid statement:

1
2
3
4
5
6
Box<float> b( 5, 8, 10 );

float scale = 0.5f;

Box<float> r = b * scale;


Something like this could make that possible, inside the box class:

1
2
3
4
5
6
7

Box< T > operator * (const T & s ) const
  {
   Box< T > r( length * s, width * s, height * s );
   return r;
  }


Now, I haven't bother to test compile this, but the idea is to create a box you can return from this function of the appropriate type, initializing it with the members length, width & height scaled by s.

This is an example of a member function operator overload. It assumes that where I wrote "Box<float> r = b * scale;", the "b" is the object upon which the "*" operator is called, and therefore it is b's length, width and height you are scaling to produce a box which is returned, and becomes a temporary object used to initialize r (which I haven't dealt with here).

Something like that is possible.

Subtraction of 3D shapes is actually quite a study, and not likely something you want to tangle with just yet.
Last edited on
Thank you so much for going in-depth!! I definitely understand it better now
Topic archived. No new replies allowed.