We continue our work with class Point, using a dynamically allocated point representation. It may be beneficial to review the two version of the classes (together with client programs) on the accompanying slide.
In the version below we add a copy constructor to class Point. This constructor turns out to be problematic.
// Redoing the example - same header file as the previous version. class Point { private: double *point_representation; public: Point(); Point(double, double); Point(const Point&); // A new copy constructor ~Point(); // Destructor double getx () const; double gety () const; void move(double dx, double dy); }; std::ostream& operator<<(std::ostream&, const Point&);
The class is implemented as follows:
#include <cmath> #include <iostream> #include "point.h" Point::Point() : point_representation{new double[2]{0.0, 0.0}} { } Point::Point(double x_coord, double y_coord) : point_representation{new double[2]{x_coord, y_coord}}{ } Point::Point(const Point& p): point_representation(p.point_representation){ // ATTEMPTING copy construction. } Point::~Point(){ std::cout << "Deleting point" << "(" << getx() << "," << gety() << ")" << std::endl; delete[] point_representation; } double Point::getx () const{ return point_representation[0]; } double Point::gety () const{ return point_representation[1]; } void Point::move(double dx, double dy){ point_representation[0] += dx; point_representation[1] += dy; } std::ostream& operator<<(std::ostream& s, const Point& p){ return s << "(" << p.getx() << "," << p.gety() << ")" ; }
There are problems in the following program: (1) When point r is moved (using the move member function) s is also moved. This is not as intended. In addition, the program aborts on exit from the function f.
#include <iostream> #include "point.h" using namespace std; int f(){ Point p, q, r(11.0, 12.0); cout << "Point p: " << p << endl; // (0,0) cout << "Point q: " << q << endl; // (0,0) cout << "Point r: " << r << endl; // (11,12) Point s(r); // s is intended to be a copy of r. cout << "Point s: " << s << endl << endl; // (11,12) r.move(1.0, 2.0); // Moves r. cout << "Point s: " << s << endl; // (12,14) !! s is ALSO MOVED - why? cout << "Point r: " << r << endl << endl; // (12,14) // PROGRAM ABORTS ON EXIT FROM F - why? } int main(){ f(); }
Explain both of the problems, and make a correct version of class Point.