Отлавливать изменения данных объекта
От: denisku Россия  
Дата: 02.10.05 18:33
Оценка:
Доброго времени суток!

Что нужно: нужно отлавливать изменения данных объекта.
Зачем это нужно: имеется некий класс, довольно тяжеловесный. Объекты этого класса хранятся, допустим, в файле(в принципе, это не обязательно файл). В программе они зачитываются в контейнер и дальше идет работа с ними. После завершения работы надо бы вернуть эти объекты. Дык вот, надо бы понять, какие объекты обновились, а какие использовались только для чтения, чтобы можно было записать(либо передать по сокетам, либо еще что...) только обновившиеся объекты.
Идея: идея проста — отлавливать вызовы неконстантных методов класса и выставлять флаг о том, что объект изменился.
Как реализовывать: можно, конечно, в каждом неконстантном методе вызывать некую функцию типа updated(), которая будет выставлять флаг... Но, ИМХО, это не выход, так как надо постоянно об этом помнить. А пир дальнейшей поддержке продукта это будет очень проблематично.

Хотелось бы иметь какой-нибудь враппер над объектом, который будет отслеживать вызовы неконстантных методов. Но как реализовать данный враппер — ума не приложу .
Была идея сделать нечто подобное, но, естественно, работает оно неправильно — вызов неконстантного operator-> не гарантирует вызов неконстантного метода объекта...(хм... нагрузил)
Вот идея, которая неправильная
// базовый класс враппера для инициализации флага
class changes_traker_base {
        bool m_is_changed;

    public:
        changes_traker_base() : m_is_changed(false) {}

        void changed() {
            m_is_changed = true;
        }

        bool is_changed() const {
            return(m_is_changed);
        }
};
//---------------------------------------------------
// сам враппер
// реализуется а-ля смарт поинтер
template <typename T>
class changes_traker : private changes_traker_base {
        T m_object; // "охраняемый" объект

    public:
        // конструкторы - неизвестно, сколько параметров нужно охраняемому объекту
        // для корректного создания.
        // В конечной реализации будут все для примерно 10 параметров - думаю, хватит
        changes_traker() {}
        
        template <typename A>
        changes_traker(const A& a) : m_object(a) {}

        template <typename A, typename B>
        changes_traker(const A& a, const B& b) : m_object(a, b) {}

        template <typename A, typename B, typename C>
        changes_traker(const A& a, const B& b, const C& c) : m_object(a, b, c) {}


        // собсно, то, на чем хотел сыграть - на константности оператора
        // Но так как его константность абсолютно не связана с константностью объекта - облом :(
        T* operator-> () {
            changed();
            return(&m_object);
        }

        const T* operator-> () const {
            return(&m_object);
        }

        bool is_changed() const {
            return(changes_traker_base::is_changed());
        }
};
//---------------------------------------------------
// подопытнй кролик
class test_class {
        int m_data;

    public:
        test_class(const int data) : m_data(data) {}

        int get_data() const {
            return(m_data);
        }

        void set_data(const int data) {
            m_data = data;
        }
};
//---------------------------------------------------
int main(int argc, char** argv) {
    changes_traker<test_class> test(5);

    std::cout << test.is_changed() << std::endl;

    std::cout << test -> get_data() << std::endl;
    std::cout << test.is_changed() << std::endl;

    test -> set_data(10);

    std::cout << test.is_changed() << std::endl;
    return(0);
}

Вывод:

0
5
1
1

Так вот, на данный момент я не знаю, как бы мне реализовать сабж. Какие будут мысли?
Извините за потраченный траффик..
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.