Я реализовал вариант любопытно повторяющегося шаблона шаблона:
#include "stdafx.h"
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
template<typename T>
struct Indexed
{
private:
static int s_maxIndex;
static std::map<int, T> s_map;
int m_index;
void SetNewIndex () { m_index = ++s_maxIndex; }
protected:
Indexed (T&& t)
{
SetNewIndex ();
s_map.insert (std::pair<int, T> (m_index, std::move (t)));
}
T& GetMappedRef () { return s_map[m_index]; }
static T& GetMappedRef (int index) { return s_map[index]; }
public:
int GetIndex () const { return m_index; }
static std::map<int, Indexed> const& GetAll () { return s_map; }
static void Clear () { s_map.clear (); }
};
template<typename T>
int Indexed<T>::s_maxIndex = 0;
template<typename T>
std::map<int, T> Indexed<T>::s_map;
struct MyObj
{
int m_myData;
MyObj () = default;
MyObj (int data)
:m_myData (data)
{
}
};
struct MyObjHandler : public Indexed<MyObj>
{
MyObjHandler (int value)
:Indexed (MyObj (value))
{
}
MyObj& GetObjRef ()
{
return GetMappedRef ();
}
static MyObj& GetObjRef (int index)
{
return GetMappedRef (index);
}
};
void test ()
{
MyObjHandler objH1 (4), objH2 (5);
std::cout << objH1.GetIndex () << ", " << objH2.GetIndex () << std::endl;
std::cout << objH1.GetObjRef().m_myData << ", " << objH2.GetObjRef().m_myData << std::endl;
}
int _tmain (int argc, _TCHAR* argv[])
{
test ();
_CrtDumpMemoryLeaks ();
system ("pause");
return 0;
}
Вот два примера, когда использование «MyObjHandler» вместо «MyObj» имеет смысл:
- Для представления графа, в котором каждый узел связан с экземпляром «MyObj». Мы сохраняем в каждом узле графа индекс и используем глобальное сопоставление для получения соответствующего экземпляра «MyObj».
Создание экземпляра «MyObj» в области делает этот экземпляр выпадающим из области действия в конце области:
недействительным CreateObj () {
объект MyObj;
//операции над объектом;
} //объект выходит за рамки
Но я хочу сохранить этот экземпляр для дальнейшего использования. Поэтому мне нужно использовать силу семантики перемещения.
Вроде работает, но дает утечки памяти:
Обнаружены утечки памяти!
Сброс объектов ->
{216} обычный блок по адресу 0x0063D1A0, длина 24 байта. Данные: ‹ c H c c
A8 D0 63 00 48 D1 63 00 A8 D0 63 00 00 00 CD CD
{215} обычный блок по адресу 0x0063D148, длина 24 байта. Данные: ‹ c c c
A8 D0 63 00 A8 D0 63 00 A0 D1 63 00 01 00 CD CD
{214} нормальный блок по адресу 0x0063D100, длина 8 байт. Данные: ‹@ > 40 A3 14 01 00 00 00 00
{213} normal block at 0x0063D0A8, 24 bytes long. Data:
48 D1 63 00 48 D1 63 00 A0 D1 63 00 01 01 CD CD
Дамп объекта завершен.
Почему?