// demonstration of common memory leak #include #include #include #include #include #include using namespace std; const double conv = 45.0/atan(1.0); class GPScoords { public: virtual ~GPScoords() { } virtual void load(istream &is) { is >> lat >> lon; lat /= conv; lon /= conv; } virtual void save(ostream &os) const { os << lat*conv << ' ' << lon*conv; } double distance(const GPScoords &gps) const { return acos(sin(lat)*sin(gps.lat) + cos(lat)*cos(gps.lat)*cos(lon-gps.lon))*6371.0; } private: double lat, lon; }; class GPStag : public GPScoords { public: virtual ~GPStag() { } virtual void load(istream &is) { GPScoords::load(is); is >> mytag; } virtual void save(ostream &os) const { GPScoords::save(os); os << ' ' << mytag; } void settag(const string &s) { mytag = s; } string tag() const { return mytag; } // prefer this to returning // "const string &" as this return can bind to an rval ref private: string mytag; }; typedef unique_ptr GPSptr; GPSptr loadGPS(istream &is) { char c; is >> c; GPSptr ret; if (c=='T') ret = GPSptr(new GPStag()); else { is.putback(c); ret = GPSptr(new GPScoords()); } ret->load(is); return ret; } class distsort { public: distsort(shared_ptr ¢er) : c(center) { } bool operator()(const GPSptr &p1, const GPSptr &p2) { return c->distance(*p1) < c->distance(*p2); } private: const shared_ptr c; }; int main(int argc, char **argv) { fstream file; file.exceptions(ifstream::eofbit); vector locs; shared_ptr center; try { file.open(argc>1 ? argv[1] : "testgps2.txt"); int n; file >> n; if (n) center = loadGPS(file); // note initializing shared_ptr // from non-const rval unique_ptr -- okay! for(int i=1;isave(cout); cout << endl; for(auto &x : locs) { // need & here (otherwise, asking for copy of ptr) x->save(cout); cout << endl; } }