Start learning free

LESSON 247 OF 568 · FUNCTIONS & CLASSES

Rectangle Class in C++: Fields, Constructor and Methods

Practice O(1) Read the full explanation

A class bundles some values with the questions you can ask about them. Write a class Rectangle that remembers a rectangle's width and height, and can tell its area, its perimeter, and whether it is a square.

Implement the class Rectangle:

  • Rectangle(width, height) creates a rectangle with the given sizes.
  • area() returns the area of the rectangle: its width times its height.
  • perimeter() returns the perimeter: the length all the way around, twice the width plus twice the height.
  • isSquare() returns true if the width and the height are equal, and false otherwise.

Each line of the input is one rectangle: its width and its height. The test code first creates a Rectangle for every line, then asks each of them, in order, for its area, its perimeter and whether it is a square, and prints the three answers on one line, the boolean as True or False. So each object must keep its own sizes. The starter code spells these names the way your language does (in Go and Rust, Rectangle is a struct with methods).

 

Example 1:

Input:
    Rectangle(3, 4)
Output: 12 14 False
Explanation: The area is 3 · 4 = 12. Going around, the sides are 3 + 4 + 3 + 4 = 14.
The width and the height differ, so it isn't a square.

Example 2:

Input:
    Rectangle(5, 5)
Output: 25 20 True
Explanation: 5 · 5 = 25, and 4 sides of 5 make 20. Both sizes are 5: a square is a rectangle with equal sides.

Example 3:

Input:
    Rectangle(2, 10)
    Rectangle(10, 2)
Output:
20 24 False
20 24 False
Explanation: Two objects, each with its own sizes. Turning a rectangle on its side changes neither its area nor its perimeter.

 

Constraints:

  • 1 <= width, height <= 104
  • At most 10 rectangles per test.

Note:

Each method needs only the two sizes, so each one runs in O(1) time.

STEP 1 OF 5
    Ctrl + Enter to check

    C++ · FUNCTIONS & CLASSES

    Rectangle Class in C++, explained

    Problem overview

    A class bundles some values with the questions you can ask about them. Here, Rectangle remembers a width and a height and answers three questions: area() is width times height, perimeter() is twice the width plus twice the height, and isSquare() tells whether the two sizes are equal.

    For a 3 by 4 rectangle the area is 12, the perimeter is 3 + 4 + 3 + 4 = 14, and it is not a square. For 5 by 5 the area is 25, the perimeter is 20, and it is a square. Each object keeps its own sizes, so two rectangles never interfere with each other: a 2 by 10 and a 10 by 2 both have area 20 and perimeter 24.

    Approach

    The class needs only the two sizes, so it stores two int fields and every method works from them. Nothing has to be looped over or looked up, so each method runs in constant time.

    Step by step

    1. Declare the fields. Under public:, write int width; and int height;. Every Rectangle object gets its own copy of both.
    2. Store the constructor's parameters. The parameters have the same names as the fields, so inside the constructor plain width means the parameter and this->width means the field of the object being built. Write this->width = width; and the same for the height.
    3. area returns width * height. Inside a method, width and height are the fields of the object the method was called on.
    4. perimeter returns 2 * (width + height). The parentheses make the addition happen first.
    5. isSquare returns width == height. A comparison is already a bool, so no if is needed.

    The solution in C++

    class Rectangle {
    public:
        int width;
        int height;
    
        Rectangle(int width, int height) {
            this->width = width;
            this->height = height;
        }
    
        int area() {
            return width * height;
        }
    
        int perimeter() {
            return 2 * (width + height);
        }
    
        bool isSquare() {
            return width == height;
        }
    };

    Using the class looks like this:

    #include <iostream>
    using namespace std;
    
    // the class above goes here
    int main() {
        cout << boolalpha;
        Rectangle a(3, 4);
        Rectangle b(5, 5);
        cout << a.area() << " " << a.perimeter() << " " << a.isSquare() << endl;
        cout << b.area() << " " << b.perimeter() << " " << b.isSquare() << endl;
        Rectangle c(2, 10);
        Rectangle d(10, 2);
        cout << c.area() << " " << c.perimeter() << " " << d.area() << " " << d.perimeter() << endl;
    }

    It prints:

    12 14 false
    25 20 true
    20 24 20 24

    The lesson's tests print the booleans as True and False; C++'s cout prints 1 and 0 unless you add boolalpha, as the example above does.

    Details worth knowing

    • The class ends with a semicolon. }; after the closing brace is required in C++, and forgetting it gives a confusing compiler error.
    • public: matters. Members of a class are private by default, so without public: the code that creates the objects couldn't call the constructor or the methods.
    • this-> is a pointer access. this points to the current object, so its fields are reached with ->. Writing width = width; would assign the parameter to itself and leave the field uninitialised.
    • Methods that only read can be const. Writing int area() const promises the method won't change the object, and the compiler enforces it. The lesson's code leaves const out to keep the first class simple, and both forms work with the lesson's tests. Marking read-only methods const becomes a habit worth forming once the basics are comfortable.

    What each object remembers

    The last two rectangles in the example are worth a second look. c is built with width 2 and height 10, and d with width 10 and height 2. They are two separate objects: changing one would never touch the other, because each carries its own width and height. Their areas and perimeters match because multiplication and addition don't care about order, not because the objects share anything. Turning a rectangle on its side changes neither number.

    The same holds for a square. Rectangle(5, 5) is not a different kind of object: it is a rectangle whose two fields happen to be equal, which is exactly what isSquare() checks.

    Another way: the initializer list

    C++ has a second way to fill in fields, written between the constructor's parameter list and its body. Each field is followed by the value for it in parentheses, and because the parameter and the field may share a name, width(width) reads naturally: the field goes outside the parentheses, the parameter inside.

    #include <iostream>
    using namespace std;
    
    class Rect {
    public:
        int width;
        int height;
        Rect(int width, int height) : width(width), height(height) {}
        int area() { return width * height; }
    };
    
    int main() {
        Rect r(3, 4);
        cout << r.width << " " << r.height << " " << r.area() << endl;
    }

    This prints:

    3 4 12

    Both forms give the same objects. The lesson's steps use the assignments inside the body, so the solution above does too. The initializer list becomes more useful later, for example when a parent class's constructor has to be called, as in the Employee and Manager lesson.

    Testing

    Try a few more inputs in a program of your own and compare with what you expect by hand. Rectangle(1, 1) should give area 1, perimeter 4 and a square. Rectangle(1, 10000) should give area 10000 and perimeter 20002. With the largest sizes the lesson allows, 10000 by 10000, the area is 100000000, which still fits comfortably in an int.

    Common mistakes

    • Computing the perimeter as 2 * width + height, which doubles only one side.
    • Returning from isSquare with a single =, which assigns instead of comparing.
    • Leaving out the return in a method that returns a value: the method then has undefined behaviour in C++.
    Keep going with C++500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free