Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution:
Methods in class Point and class Rectangle


Here follows my programw with the area and move methods. These program relies on methods that establish references to corner points from rectangle.

point.h:

class Point {
private: 
  double x, y;

public:
  Point();                    
  Point(double x);            
  Point(double x, double y);  

  double getx () const;
  double gety () const;
  void move(double dx, double dy) ;
};

std::ostream& operator<<(std::ostream&, const Point&);

point.cc:

#include <cmath>
#include <iostream>
#include "point.h"


Point::Point(): x(0.0), y(0.0){
}

Point::Point(double x_coord): x(x_coord), y(0.0){
}

Point::Point(double x_coord, double y_coord): x(x_coord), y(y_coord){
}

double Point::getx () const{
  return x;
}

double Point::gety () const{
  return y;
}

void Point::move(double dx, double dy){
  x += dx; y += dy;
}

std::ostream& operator<<(std::ostream& s, const Point& p){
  return s << "(" << p.getx() << "," << p.gety() << ")" ;
}

rect.h:

#include "point.h"

class Rectangle{
private:
  Point upper_left, lower_right;

public:
  Rectangle();
  Rectangle(Point p1, Point p2);
  Rectangle(double x1, double y1, double x2, double y2);
 
  void move(double dx, double dy);
  double area() const;                        
  Point& get_upper_left_point() const;   // Returns Point& in this version!
  Point& get_lower_right_point() const;
};

std::ostream& operator<<(std::ostream&, const Rectangle&);

  

rect.cc:

#include <cmath>
#include <iostream>
#include "rect.h"

Rectangle::Rectangle(): upper_left(-1,1), lower_right(1,-1){
}

Rectangle::Rectangle(Point p1, Point p2): upper_left(p1), lower_right(p2){
}

Rectangle::Rectangle(double x1, double y1, double x2, double y2):
      upper_left(x1,y1), lower_right(x2,y2){
}

void Rectangle::move(double dx, double dy){
  upper_left.move(dx, dy);
  lower_right.move(dx, dy);
}

Point& Rectangle::get_upper_left_point() const{
  return const_cast<Point&>(upper_left);            // const cast seems necessary here. Why?
}

Point& Rectangle::get_lower_right_point() const{
  return const_cast<Point&>(lower_right);           // const cast seems necessary here. Why?
}

double Rectangle::area() const{
  return (lower_right.getx() - upper_left.getx()) * (upper_left.gety()- lower_right.gety());
}

std::ostream& operator<<(std::ostream& s, const Rectangle& r){
 return s << "[" << r.get_upper_left_point() << "," << r.get_lower_right_point() << "]" ;
}


Sample client program:

#include <iostream>
#include "rect.h"

using namespace std;

int main(){
  Point p1(1,2), p2(5,-3);
  Rectangle r1,                             // Use default constructor
            r2(1,2,5,-3),                   
            r3(Point(1,2), Point(5,-3));

  cout << "r1: " << r1 << " Area: " << r1.area() << endl;
  cout << "r2: " << r2 << " Area: " << r2.area() << endl;
  cout << "r3: " << r3 << " Area: " << r3.area() << endl;


  // OK:
  cout << "r3 before move: " << r3 << endl;
  r3.move(1,2);
  cout << "r3 after move: " << r3 << endl;

  // Does not work:
  cout << "r2 before move: " << r2 << endl;
  Point c1 = r2.get_upper_left_point(),     // Copies of corners.
        c2 = r2.get_lower_right_point();

  c1.move(1,1); c2.move(1,2);  // Does not work. Move copies of points
  cout << "r2 after move: " << r2 << endl;

  // Works:
  cout << "r2 before move: " << r2 << endl; 
  r2.get_upper_left_point().move(1,1); r2.get_lower_right_point().move(1,2);    
  cout << "r2 after move: " << r2 << endl;
}