C++マップを使用して、基本クラスと派生クラスへのポインタを格納する際に問題があります。実行時にstd :: map、polymorphism and delete
#include <map>
#include <iostream>
struct foo{ int dummy[4]; };
struct bar{ int additionnal[4]; };
class Base
{
private:
struct foo *_internal_structure;
public:
Base() { _internal_structure = new struct foo; }
~Base()
{
delete _internal_structure;
std::cout << "Base DTOR\n";
}
};
class Derived: public Base
{
private:
struct bar *_additional_structure;
public:
Derived() { _additional_structure = new struct bar; }
~Derived()
{
delete _additional_structure;
std::cout << "Derived DTOR\n";
}
};
int main(int argc, char *argv[])
{
std::map<int, Base*> my_map;
Base *to_add = new Base();
Derived *derived_to_add = new Derived();
my_map[1] = to_add;
my_map[2] = derived_to_add; // works, derived class, but object gets sliced
/// clear hash map ///
std::map<int, Base*>::const_iterator iter;
for(iter = my_map.begin(); iter != my_map.end(); ++iter)
{
delete (*iter).second;
}
return 0;
}
結果:
私はかなり長いが、簡単なコードで説明しましょう
Base DTOR
Base DTOR
だから、私は私のマップに派生クラスポインタを挿入する事は、あります基礎となるオブジェクトはBaseクラスとみなされます。そのため、呼び出されるデストラクタは、Derivedクラスではなく、Baseクラスの1つです。 Valgrindは私が毎回16バイトを失うことを確認します。
また、私はブーストのshared_ptrの(I saw some mentions of it here)を使用することはできませんし、私が使用埋め込まれたアーキテクチャでは、C++例外と(私の場合には、いくつかのアンアラインドアクセスやその他の悪いものが発生する)RTTI をサポートしていません。 (編集:関連しません)。
この動作をどのように修正できるかご存知ですか?
あなたの質問には関係ありませんが、それらのデータメンバはplainの代わりに 'boost :: scoped_ptr'または' const std :: auto_ptr'ポインタ。 –
@Tadeusz:私はブーストを使用することはできません、私は最後の段落でそれを言う:)私はauto_ptr、おかげで調べます。 – Gui13
最新のコンパイラには、Boostから新しいC++標準に伝えられているものがあります。現在のVisual C++(あるいはGCCと思っています)の場合は、 'std :: unique_ptr'または' std :: shared_ptr'を参照してください。 –