Metoda szablonowa zamiast rzutowania

Uwaga! Informacje na tej stronie mają ponad 5 lat. Nadal je udostępniam, ale prawdopodobnie nie odzwierciedlają one mojej aktualnej wiedzy ani przekonań.

# Metoda szablonowa zamiast rzutowania

11:09
Tue
29
Jan 2008

Wpadłem ostatnio na pomysł, żeby się z wami podzielić drobnym rozwiązaniem, które wymyśliłem i które stosuję od dawna w swoim kodzie. Jako przykład weźmy manager zasobów. U mnie jest jeden ogólny, a każda klasa zasobu dziedziczy ze wspólnej klasy bazowej IResource. Są więc klasy pochodne takie jak D3dTexture czy FmodSound. Zasobów używam przez wskaźnik, ale ponieważ ich lista jest zapisana w pliku tekstowym, trzeba taki wskaźnik najpierw pobrać na podstawie nazwy. Trzeba przy tym zrzutować otrzymany zasób w dół na określony typ pochodny. Można to zrobić tak:

res::D3dTexture *Tex =
  (res::D3dTexture*)res::g_Manager->MustGetResource(L"Potwór01");
Tex->Cośtam();

lub bezpieczniej ze względu na typ:

res::D3dTexture *Tex =
  dynamic_cast<res::D3dTexture*>(res::g_Manager->GetResource(L"Potwór01"));
if (Tex == NULL) throw Error(...);
Tex->Cośtam();

Mój pomysł polega na napisaniu metody szablonowej, która ukryje rzutowanie:

template <typename T>
T * MustGetResourceExf(const wstring &Name)
{
  return static_cast<T*>(MustGetResource(Name));
}

I jej wersji wolniejszej ale bezpieczniejszej:

template <typename T>
T * MustGetResourceEx(const wstring &Name)
{
  IResource *R = MustGetResource(Name);
  if (typeid(*R) != typeid(T)) throw Error(...);
  return static_cast*lt;T*>(R);
}

Używa się ich tak:

res::D3dTexture *Tex =
  res::g_Manager->MustGetResourceEx<res::D3dTexture>(L"Potwór01");
Tex->Cośtam();

Prawda, że bardziej eleganckie? :) Gdyby ktoś pytał, przedrostek "Must" oznacza u mnie, że w przypadku nieznalezienia zasobu o podanej nazwie rzucony zostaje wyjątek, w przeciwieństwie do metod bez niego, które w takim przypadu zwracają NULL.

Comments | #c++ #algorithms Share

Comments

STAT NO AD
[Stat] [STAT NO AD] [Download] [Dropbox] [pub] [Mirror]
Copyright © 2004-2017