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(...) {}
}
バルグリンとプログラムをコンパイルすると、次のエラーが表示されます。純粋な仮想メソッドと呼ばれます。アクティブな例外なしで終了しました。サイズ8の無効な読み取り。
初期化で私が誤ってしていることについての洞察はありますか?
私の疑いは、私が未成年の記憶から読んでいることです。
編集:
そのため、Destructorでは、終了コマンドの前に次のコード行を追加し、メモリリークとエラーがすべて消えました!
if(parser)parser.reset();
パーサーへのすべての参照は、それを扱うことができる前に消えなければならないのはなぜですか?
ありがとう、ありがとう。
解決
xercesdomparserのDestructorを呼び出す前に、xmlplatformutils :: terminate()を呼び出します。メンバー変数のデストラクタは、デストラクタボディが実行された後に呼び出されます。メンバー変数は宣言の順に構築され、逆に破壊されます。
あなたはこのようなことをすることができます:
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) { }
};
デフォルトのデストラクタを使用してください。コンストラクターと課題オペレーターをコピーしたい場合は、それに対処する必要があります。
ああ、そして例外を捕まえて捨てることはおそらく悪い考えです...
所属していません StackOverflow