Problem:
I have a properties dialog. X objects build the dialog, but a subclass
of X, such as Y, can add more options to the dialog for Y specific
properties. I would like to write code for the dialog that creates a
backup of the current object when the dialog pops up, and sets the
current modified object to the backup when the user clicks cancel (or
discards the backup if the user clicks OK). X already has a Clone
method.
(I realize this way of making backups isn't always practical for large
objects, but the ones I'm dealing with are fairly lightweight)
Solutions:
0. Simply write the code using X pointers. Problem: Then only the X
members get set because the assignment operator can't be virtual.
1. Template the dialog class so you can do Dialog<Xor Dialog<Y>,
causing a backup of the appropriate type to be made. Problem: The
dialog code gets a lot uglier just to make 1 line work.
2. Solution below seemed best, but I'm looking for feedback.
This is a compileable test case.
#include <iostream>
template<class T>
class CanBackup {
public:
CanBackup();
~CanBackup();
void MakeBackup();
void RestoreBackup();
virtual CanBackup<T>* Clone() = 0;
private:
T* backup;
};
template<class T>
CanBackup<T>::CanBackup()
: backup(NULL)
{
}
template<class T>
CanBackup<T>::~CanBackup()
{
if(backup)
delete backup;
}
template<class T>
void CanBackup<T>::MakeBackup()
{
backup = (T*)Clone();
}
template<class T>
void CanBackup<T>::RestoreBackup()
{
*((T*)this) = *backup;
}
class A : public CanBackup<A{
public:
A();
~A();
A* Clone();
int x;
};
A::A() {}
A::~A() {}
A* A::Clone()
{
return new A(*this);
}
// Should print: 3 5 3
// Actually prints: 3 5 5
int main() {
A foo;
foo.x = 3;
std::cout << foo.x << std::endl;
foo.MakeBackup();
foo.x = 5;
std::cout << foo.x << std::endl;
foo.RestoreBackup();
std::cout << foo.x << std::endl;
}