Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

libs/serialization/example/demo_exception.cpp

Boost , ,

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

libs/serialization/example/demo_exception.cpp

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_exception.cpp
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . 
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Example of safe exception handling for pointer de-serialization
// 
// This example was prepared by Robert Ramey to demonstrate and test 
// safe exception handling during the de-serialization of pointers in
// a non-trivial example.
//
// Hopefully, this addresses exception issues raised by
// Vahan Margaryan who spent considerable time and effort
// in the analysis and testing of issues of exception safety 
// of the serialization library.
#include <algorithm>
#include <iostream>
#include <cstddef> // NULL
#include <fstream>
#include <string>
#include <cstdio> // remove
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{ 
    using ::remove;
}
#endif
#include <boost/archive/tmpdir.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#endif
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/split_member.hpp>
template<class TPTR>
struct deleter
{
    void operator()(TPTR t){
        delete t;
    }
};
class Course;
class Student;
class Student
{
public:
    static int count;
    Student(){
        count++;
    }
    ~Student(){
        some_courses.clear();
        count--;
    }
    std::list<Course *> some_courses;
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar & some_courses;
    }
};
int Student::count = 0;
class Course
{
public:
    static int count;
    Course(){
        count++;
    }
    ~Course(){
        // doesnt delete pointers in list
        // since it doesn't "own" them
        some_students.clear();
        count--;
    }
    std::list<Student *> some_students;
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar & some_students;
    }
};
int Course::count = 0;
class School
{
public:
    ~School(){
        // must delete all the students because
        // it "owns" them
        std::for_each(all_students.begin(), all_students.end(), deleter<Student *>());
        all_students.clear();
        // as well as courses
        std::for_each(all_courses.begin(), all_courses.end(), deleter<Course *>());
        all_courses.clear();
    }
    std::list<Student *> all_students;
    std::list<Course *> all_courses;
private:
    friend class boost::serialization::access;
    BOOST_SERIALIZATION_SPLIT_MEMBER()
    template<class Archive>
    void save(Archive & ar, const unsigned int file_version) const;
    template<class Archive>
    void load(Archive & ar, const unsigned int file_version);
};
#if 0
// case 1:
template<class Archive>
void School::serialize(Archive & ar, const unsigned int /* file_version */){
    // if an exeception occurs while loading courses
    // the structure courses may have some courses each
    // with students
    ar & all_courses;
    // while all_students will have no members.
    ar & all_students; // create students that have no courses
    // so ~School() will delete all members of courses
    // but this will NOT delete any students - see above
    // a memory leak will be the result.
}
// switching the order of serialization doesn't help in this case
// case 2:
template<class Archive>
void School::serialize(Archive & ar, const unsigned int /* file_version */){
    ar & all_students;
    ar >> all_courses;  // create any courses that have no students
}
#endif
template<class Archive>
void School::save(Archive & ar, const unsigned int /* file_version */) const {
    ar << all_students;
    ar << all_courses;
}
template<class Archive>
void School::load(Archive & ar, const unsigned int /* file_version */){
    // if an exeception occurs while loading courses
    // the structure courses may have some courses each
    // with students
    try{
        // deserialization of a Course * will in general provoke the
        // deserialization of Student * which are added to the list of
        // students for a class.  That is, this process will result
        // in the copying of a pointer.
        ar >> all_courses;
        ar >> all_students; // create students that have no courses
    }
    catch(std::exception){
        // elminate any dangling references
        all_courses.clear();
        all_students.clear();
        throw;
    }
}
void init(School *school){
    Student *bob = new Student();
    Student *ted = new Student();
    Student *carol = new Student();
    Student *alice = new Student();
    school->all_students.push_back(bob);
    school->all_students.push_back(ted);
    school->all_students.push_back(carol);
    school->all_students.push_back(alice);
    Course *math = new Course();
    Course *history = new Course();
    Course *literature = new Course();
    Course *gym = new Course();
    school->all_courses.push_back(math);
    school->all_courses.push_back(history);
    school->all_courses.push_back(literature);
    school->all_courses.push_back(gym);
    bob->some_courses.push_back(math);
    math->some_students.push_back(bob);
    bob->some_courses.push_back(literature);
    literature->some_students.push_back(bob);
    ted->some_courses.push_back(math);
    math->some_students.push_back(ted);
    ted->some_courses.push_back(history);
    history->some_students.push_back(ted);
    alice->some_courses.push_back(literature);
    literature->some_students.push_back(alice);
    alice->some_courses.push_back(history);
    history->some_students.push_back(alice);
    // no students signed up for gym
    // carol has no courses
}
void save(const School * const school, const char *filename){
    std::ofstream ofile(filename);
    boost::archive::text_oarchive ar(ofile);
    ar << school;
}
void load(School * & school, const char *filename){
    std::ifstream ifile(filename);
    boost::archive::text_iarchive ar(ifile);
    try{
        ar >> school;
    }
    catch(std::exception){
        // eliminate dangling reference
        school = NULL;
    }
}
int main(int argc, char *argv[]){
    std::string filename(boost::archive::tmpdir());
    filename += "/demofile.txt";
    School *school = new School();
    std::cout << "1. student count = " << Student::count << std::endl;
    std::cout << "2. class count = " << Course::count << std::endl;
    init(school);
    std::cout << "3. student count = " << Student::count << std::endl;
    std::cout << "4. class count = " << Course::count << std::endl;
    save(school, filename.c_str());
    delete school;
    school = NULL;
    std::cout << "5. student count = " << Student::count << std::endl;
    std::cout << "6. class count = " << Course::count << std::endl;
    load(school, filename.c_str());
    std::cout << "7. student count = " << Student::count << std::endl;
    std::cout << "8. class count = " << Course::count << std::endl;
    delete school;
    std::cout << "9. student count = " << Student::count << std::endl;
    std::cout << "10. class count = " << Course::count << std::endl;
    std::remove(filename.c_str());
    return Student::count + Course::count;
}

Статья libs/serialization/example/demo_exception.cpp раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 21:47:18/0.0062270164489746/0