Can I call an overloaded operator from the base class for the derived class

I have to create two classes: Building and House(derived from Building) In Building I have overloaded the operator < so that it returns true if the total area of the first building is smaller than the total area of the second. In House the same operator is overloaded so it returns true if the first house has fewer rooms than the second. Is there a way to compare two objects of House based on total area?

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
 class Building
{
protected:
	int m_height;
	int m_area;
	int m_floors;
public:
	//...
	int getTotalArea() const;

	friend bool operator<(const Building&, const Building&);
};

int Building::getTotalArea() const { return m_area*m_floors; }

bool operator<(const Building& first, const Building& second)
{
	if (first.getTotalArea() < second.getTotalArea()) return true;
	else return false;
}


class House : public Building
{
private:
	int m_rooms;
	char* m_owner;
public:
        //...
	friend bool operator<(const House&, const House&);
};

bool operator<(const House& first, const House& second)
{
	if (first.m_rooms < second.m_rooms) return true;
	else return false;
}


Edit: For the people wondering why I'm trying to do this, it was a task on a programming exam I took. I had to compare two House objects based on both rooms and area. I didn't manage to solve it and was wondering how it's done. Also, yes, I didn't post the constructors and some other functions since i thought they were not relevant to the question.
Last edited on
You can just convert them to Building references, but I question your design of this. Why do you want to do this?

Are you actually trying to implement polymorphism?

The following works (I made members be public just for ease), but I'm not sure if I agree with the overall design.
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
class Building
{
  public:
	int m_height;
	int m_area;
	int m_floors;
  public:
	//...
	int getTotalArea() const;

	friend bool operator<(const Building&, const Building&);
};

int Building::getTotalArea() const { return m_area*m_floors; }

bool operator<(const Building& first, const Building& second)
{
	if (first.getTotalArea() < second.getTotalArea()) return true;
	else return false;
}


class House : public Building
{
  public:
	int m_rooms;
	char* m_owner;
  public:
        //...
	friend bool operator<(const House&, const House&);
};

bool operator<(const House& first, const House& second)
{
	if (first.m_rooms < second.m_rooms) return true;
	else return false;
}

#include <iostream>

int main()
{
    House h1;
    Building& b1 = h1;
    
    h1.m_rooms = 3;
    h1.m_area   = 10;
    h1.m_floors = 10;
    
    House h2;
    Building& b2 = h2;
    
    h2.m_rooms = 2; 
    h2.m_area   = 20;
    h2.m_floors = 20;
    
    bool result;
    
    result = h1 < h2;
    std::cout << std::boolalpha << result << std::endl;
    
    result = b1 < b2;
    std::cout << std::boolalpha << result << std::endl;
    
}


___________________________________________________

My gut feeling doesn't like this because you are making the base class's operator significantly different than the sub class, in such a way that it's possible for the sub class's < operator to return true while having the base class's < operator return false.

Possibly operator overloading abuse. To me, it would make more sense if, when comparing two Houses, you first compare their Building, and if the Buildings are equal, then you should look at the House property.

Sort of like when you compare a person's name, you would first compare last names (Buildings), then first names (Houses).
Last edited on
Guessing some parts are missing, specifically how m_area is initialized (Building constructor or so).
What happens if you delete everything from line 30 down? --> Can't you then just compare two Houses with that global bool operator< method?

I would also suggest removing all the friend stuff and just implement the operator inside Building.
Example of how I envisioned it:
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
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Building
{
public:
    Building(string owner, int rooms, double area) : 
        owner(owner),
        rooms(rooms),
        area(area)
    {        
    }
    friend ostream& operator<<(ostream &os, const Building& b);

    bool operator<(const Building& other) const
    {
        return area < other.area;
    }

protected:
    string owner;
    int rooms;
    double area;    
};

// Helper to send Building to an output stream
ostream& operator<<(ostream& os, const Building& b)
{
    os << setw(20) << b.owner << 
          setw(8) << b.rooms << 
          setw(12) << b.area << endl;
    return os;
}

class House : public Building
{
public:
    House(string family, string owner, int rooms, double area) : 
        family_(family),
        Building(owner, rooms, area)
    {        
    }

private:
    string family_;    
};

int main()
{
    vector<House> houses 
    {
        {"Smith", "John Smith", 8, 980.7 },
        {"Jones", "Jane Jones", 6, 802.3},
        {"Rawr", "Meow Rawr", 9, 844.4 }
    };
    sort(houses.begin(), houses.end());

    cout << setw(20) << "Owner" << 
            setw(8) << "Rooms" << 
            setw(12) << "Area" << endl;
    for (auto& house : houses)
        cout << house;

    return 0;
}


Running at https://repl.it/@icy_1/FinancialShabbyWatchdog

               Owner   Rooms        Area
          Jane Jones       6       802.3
           Meow Rawr       9       844.4
          John Smith       8       980.7
Last edited on
Topic archived. No new replies allowed.