Оператор new
был очевидным виновником там. Использование автоматических переменных решает утечку памяти. Код улучшается, когда такие классы, как Shape и TwoPoint, могут передаваться как ссылки, а не как скопированные значения. Я допускаю, что мне немного скучно и немного возиться с вашим кодом, даже добавлю вывод отладки с помощью ostream. Я не могу помочь вам с логикой приложения, хотя. Я понятия не имею, почему существуют определенные конструкции, поэтому я сохранил большинство из них нетронутыми (за исключением val_new, потому что в настоящее время ничего не добавляет в код).
#include <iostream>
#include <math.h>
using namespace std;
class TwoPoint {
int value, width;
public:
TwoPoint() : value(0), width(0) {}
TwoPoint(int v, int w) : value(v), width(w) {}
TwoPoint(const TwoPoint& t) : value(t.value), width(t.width) {}
int getWidth() { return width; }
int getValue() { return value; }
TwoPoint & plus(int newval) { value += newval; return *this; }
friend ostream& operator<< (ostream& os, const TwoPoint& x);
};
template <class T> class Shape;
template <class T>
ostream& operator<< (ostream& os, const Shape<T>& x);
template <class T>
class Shape {
T val; // do you really need val_new?
public:
Shape(T initval) : val(initval) {}
T & get() { return val; }
void set (T const & newval) { val = newval; }
// not sure why you used and set val_new instead of val...
friend ostream& operator<< <> (ostream& os, const Shape<T>& x);
};
class Rectangle {
private:
Shape<TwoPoint> val;
bool incr_called, decr_called, load_called;
TwoPoint newval;
public:
Rectangle(TwoPoint i) : val(Shape<TwoPoint> (i)),
incr_called(false), decr_called(false), load_called(false) {}
Shape<TwoPoint> & read() { return val; }
void load(const TwoPoint& n) { load_called = true; newval = n; }
void increment() { incr_called = true; }
void decrement() { decr_called = true; }
void init() { incr_called = decr_called = load_called = 0; }
void actions() {
if (load_called) {
val.set(TwoPoint(newval));
load_called = false; // should the flag be reset?
}
if(incr_called && !decr_called) {
val.set(val.get().plus(1));
incr_called = false; // should the flag be reset?
}
if(!incr_called && decr_called) {
val.set(val.get().plus(-1));
decr_called = false; // should the flag be reset?
}
}
friend ostream& operator<< (ostream& os, const Rectangle& x);
};
// added for debug printouts:
ostream& operator<< (ostream& os, const TwoPoint& x){
os << "TwoPoint( " << x.value << ", " << x.width << " )";
return os;
}
template <class T>
ostream& operator<< (ostream& os, const Shape<T>& x){
os << "Shape( " << x.val << " )";
return os;
}
ostream& operator<< (ostream& os, const Rectangle& x){
os << "Rectangle( " << x.val
<< (x.load_called ? ", load_called" : "")
<< (x.incr_called ? ", incr_called" : "")
<< (x.decr_called ? ", decr_called" : "")
<< " )";
return os;
}
int main() {
TwoPoint tp(800, 300);
cout << "Creating a Rectangle using " << tp << endl;
Rectangle r(tp);
cout << r << endl;
r.load(TwoPoint(100, 200));
cout << r << endl;
r.actions();
cout << r << endl;
r.increment();
cout << r << endl;
r.actions();
cout << r << endl;
r.decrement();
cout << r << endl;
r.actions();
cout << r << endl;
return 0;
}
И вывод программы:
Creating a Rectangle using TwoPoint( 800, 300 )
Rectangle( Shape( TwoPoint( 800, 300 ) ) )
Rectangle( Shape( TwoPoint( 800, 300 ) ), load_called )
Rectangle( Shape( TwoPoint( 100, 200 ) ) )
Rectangle( Shape( TwoPoint( 100, 200 ) ), incr_called )
Rectangle( Shape( TwoPoint( 101, 200 ) ) )
Rectangle( Shape( TwoPoint( 101, 200 ) ), decr_called )
Rectangle( Shape( TwoPoint( 100, 200 ) ) )
Я надеюсь, что этот отладочный материал окажется полезным при дальнейшей разработке этого приложения.