// Направить указатель в стек
void push (Type* _t) { array[iTop++]=_t; }
// Вынуть указатель из стека
Type* pop (void) {
if (iTop == 0) return NULL;
else return array[--iTop];
}
// Стек пуст?
int isEmpty (void) { return iTop==0; }
// Очистить стек
void emptyAll (void) {
for (int iCounter = 0; iCounter ‹ iTop; iCounter ++)
if (*(array+iCounter)!= NULL) delete *(array+iCounter);
iTop = 0;
}
};
// Шаблон класса с многоуровневой отменой
template ‹class Type›
class MLTrans {
typedef ampstack‹Type› stack;
private:
Type* that; // Текущее значение
stack history; // контейнер предыдущих значений
public:
// конструктор-деструктор
MLTrans(): that(new Type) {}
~MLTrans () { delete that; }
// Сохранение текущего значения, aналог SAVE TRANSACTION в SQL серверах
void Push() {
history.push(that);
that = new Type(*that);
}
// удаление промежуточных состояний
void Commit () { history.emptyAll(); }
// Откат на одну позицию; уничтожает текущее значение.
void PopOne() {
if (!history.isEmpty()) {
delete that;
that = history.pop();
}
}
// Откат к началу транзакции.
void Rollback() {
Type* old = history.pop();
Type* older = NULL;
if (old!= NULL) {
while ((older = history.pop())!= NULL) {
delete old;
old = older;
}
delete that;
that = old;
}
}
// Переопределенный operator-›
Type* operator-›() { return that; }
}
// проверим работу
int main() {
int t;
MLTrans‹CType› a;
a-›set(5);
t = a-›get();
a.Push();
a-›set(6);
t = a-›get();
a.Push();
t = a-›get();
a-›set(7);
t = a-›get();
a.Push();
t = a-›get();
a-›set(9);
t = a-›get();
// a.Push();
t = a-›get();
a.PopOne();
t = a-›get();
a.Rollback();
t = a-›get();
return 0;
}
Шаг 24 - Как создавать ТОЛЬКО локальные переменные.
В Шаге 17 мы изыскали способ подавить создание локальных переменных. Решим обратную задачу - как подавить иные способы их создания. А какие иные? Любые другие способы предполагают вызов оператора operator new() для выделения памяти и потом вызов конструктора. Значит, надо объявить operator new() закрытым членом класса, да и все. Ничего в нем делать не надо, а сразу назад. Попробуем?
class CNoHeap {
public:
int a;
private: