C ++ Xerces-C: инициализация Shared_PTR
-
09-10-2019 - |
Вопрос
Я новичок в общих указателях и был задан вопросом, как инициализировать общий указатель, если это также переменная участника?
В настоящее время мой код выглядит что-то подобное: в заголовом файле у меня есть:
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.
Любое понимание того, что я могу не делать неправильно с инициализацией?
Мое подозрение - я читаю от нераспределенной памяти.
РЕДАКТИРОВАТЬ:
Таким образом, в деструкуре я добавил следующие строки кода до команды завершения и утечки памяти и ошибки всех исчезли!
Если (анализатор) Parser.Reset ();
Почему вся ссылка на анализатор должна исчезнуть до того, как она может быть освобождена?
Много ценится, спасибо.
Решение
Вы называете xmlplatformutils :: прекратить () до того, как позвонить деструктору для 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) { }
};
И просто используйте деструктор по умолчанию. Если вы хотите скопировать конструкторы и операторы назначения, вам нужно будет иметь дело с этим.
Ох, и бросая и бросание исключений, вероятно, плохая идея ...