C ++ Xerces-c: инициализация shared_ptr - PullRequest
1 голос
/ 11 января 2011

Я новичок в общих указателях, и мне было интересно, как инициализировать общий указатель, если он также является переменной-членом?

В настоящее время мой код выглядит примерно так: В заголовочном файле у меня есть:

class Parser {
   public:
      Parser();
      ~Parser();

      boost::shared_ptr<XercesDOMParser> parser;
{

В конструкторе у меня есть что-то вроде этого:

Parser::Parser() 
{
   try {
      XMLPlatformUtils::Initialize(); 
   } catch (...) {}

   parser = shared_ptr<XercesDOMParser> (new XercesDomParser()); 
}

В деструкторе у меня есть:

Parser::~Parser() {
   try {
      XMLPlatformUtils::Terminate();
   }catch(...) {}
}

Однако при компиляции программы с помощью Valgrind я получил бы следующую ошибку: Чистый виртуальный метод называется. Прекращено без активного исключения. Недопустимое чтение размера 8.

Любое понимание того, что я могу делать неправильно при инициализации?

Я подозреваю, что я читаю из нераспределенной памяти.

EDIT:

Итак, в деструкторе я добавил следующие строки кода перед тем, как команда завершения, утечки памяти и ошибки исчезли!

if (парсер) parser.reset (); * +1022 *

Почему все ссылки на синтаксический анализатор должны быть удалены, прежде чем он может быть освобожден?

Очень признателен, спасибо.

1 Ответ

2 голосов
/ 11 января 2011

Вы вызываете XMLPlatformUtils :: Terminate () перед вызовом деструктора для XercesDomParser. Деструкторы для переменных-членов вызываются после запуска тела деструктора. Переменные-члены создаются в порядке объявления и уничтожаются в обратном порядке.

Вы могли бы сделать что-то вроде этого:

class Parser : boost::noncopyable {
    struct XmlHandle {
        XmlHandle() { XMLPlatformUtils::Initialize(); }
        ~XmlHandle() { XMLPlatformUtils::Terminate(); }
    };

    XmlHandle m_handle;
    boost::shared_ptr<XercesDOMParser> m_parser;

public:
    Parser() : m_parser(new XercesDomParser) { }
};

И просто используйте деструктор по умолчанию. Если вам нужны конструкторы копирования и операторы присваивания, вам придется иметь дело с этим.

О, а ловить и выбрасывать исключения, вероятно, плохая идея ...

...