2016-07-09 9 views
-1

で使用されるマップの要素にアクセスしようとしたときだから私は、このプログラムがあります。プログラムがクラッシュした多型

#include <iostream> 
#include <memory> 
#include <map> 

enum 
{ 
    STORAGE_NONE, STORAGE_CAR, STORAGE_BUS, STORAGE_PLANE // ... 
}; 

class Car 
{ 
    public: 
     Car() : m_color("default") {}; 
     std::string getColor() { return m_color; }; 
     void setColor(std::string color) { m_color = color; } 
    private: 
     std::string m_color; 
}; 

class Storage 
{ 
    public: 
     virtual ~Storage() {} 
     virtual std::shared_ptr<Storage> clone() { return std::make_shared<Storage>(); } 
}; 

class CarStorage : public Storage 
{ 
    public: 
     CarStorage(Car& car) : m_car(car) {}; 
     ~CarStorage() {} 
     std::shared_ptr<Storage> clone() 
     { 
      return std::make_shared<CarStorage>(CarStorage(m_car)); 
     } 

     Car m_car; 
}; 

// BusStorage, PlaneStorage... 

class StorageManager 
{ 
    public: 
     StorageManager() : m_storages() {}; 
     std::shared_ptr<Storage> getStorage(int id, int storageType) 
     { 
      return m_storages[storageType][id]; 
     } 
     void addStorage(int id, int storageType, Storage& storage) 
     { 
      if(storageType == STORAGE_CAR) 
       m_storages[storageType][id] = storage.clone(); 
     } 
    private: 
     std::map<int, std::map<int, std::shared_ptr<Storage> > > m_storages; // first int is for storageType, second is for id (we can have many instances of CarStorage... for each garage) 

}; 

void foo(StorageManager& storageManager) 
{ 
    Car mycar; 
    mycar.setColor("silver"); 
    CarStorage garage(mycar); 

    storageManager.addStorage(0, STORAGE_CAR, garage); 
} 

int main() 
{ 
    StorageManager storageManager; 
    foo(storageManager); 
    std::shared_ptr<CarStorage> garage = std::static_pointer_cast<CarStorage>(storageManager.getStorage(0, STORAGE_CAR)); 
    Car car = garage->m_car; 
    std::cout << car.getColor(); 

    return 0; 
} 

をそしてfooを呼び出すときに、私が作成していた車を取得しようとしたとき、それは私のメインの中にクラッシュします。

これは私の実際のプログラムではなく、私の問題を説明するための例です。私の実際のプログラムではCarはSFMLのsf::Spriteであり、static_cast(多形のためにする必要があります)の後は、スプライトが再構成されたようなもので、fooに与えられたデータが失われました。

アイデア?ありがとう!

+0

おそらく 'm_storages'の「第2次元」に' map'sはありません。例えば、 'auto it = m_storages.find(INDEX);のように、目的のインデックスの下に何かが存在するかどうかを調べてみてください。 if(it == m_storages.end())m_storages.insert(...); ' – Patryk

+0

何の例外がありますか? – meJustAndrew

+0

自動保存期間を持つオブジェクトへのポインタを保存しています。それはうまく終わることはほとんどありません。 – molbdnilo

答えて

0

あなたは、この動作を停止するには、2つのオプションがあります:あなたはStorageManagerからあなたaddStorageに値ではなく、参照することによりCarStorageを送信

  1. を。これにより、fooの最後に削除されたオブジェクトの送信が停止され、そのコピーが作成されます。

  2. キーワードをnewキーワードでインスタンス化し、ポーラーとしてCarStorageにヒープしておきます。この方法では、オブジェクトはfooメソッドの最後に死ぬことはありません。

2番目のオプションは、十分な注意を払わないとメモリリークにさらされるため、1番に移動することをお勧めします。

+0

それは素晴らしい、ありがとう!最後の行 'std :: cout << car.getColor();'を追加したときに明らかになった2番目の問題は、 'm_color'が定義されていないかのようになります。それは 'static_cast'とリンクされていますか? – Urefeu

+0

'std :: shared_ptr 'のようなスマートポインタを 'new'と' delete'への生の呼び出しの代わりに使う方が良いです。 – PaulMcKenzie

+0

@PaulMcKenzieもっと良いC#を書いてください。すべて管理しています。 – meJustAndrew