2011-01-10 5 views
1

Я новичок в общих указателях и задавался вопросом, как инициализировать общий указатель, если он также является переменной-членом?C++ Xerces-c: Инициализация shared_ptr

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

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, я бы принял e следующая ошибка: Вызывается чистый виртуальный метод. Прекращено без активного исключения. Недопустимое считывание размера 8.

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

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

EDIT:

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

если (парсер) parser.reset();

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

Большое спасибо, спасибо.

+0

Вы уверены, что проблема локализована в shared_ptr intialization? И вы уверены, что ошибка Valgrind в этой функции? Можете ли вы предоставить более подробную информацию о том, что называется виртуальной функцией? Чем больше деталей вы предоставляете, тем лучше мы сможем помочь. – templatetypedef

+0

Я думаю, что проблема локализована только при инициализации. Если я прокомментировал 'parser = shared_ptr (новый XercesDomParser()); Вальгринд вернется без ошибок. Вся другая реализация в моем коде закомментирована, за исключением ctor и dtor, поэтому я не понимаю, откуда приходит виртуальная функция. – user459811

ответ

2

Вы вызываете 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) { } 
}; 

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^