Рассматривайте использование подтипирования как подробность реализации.
Существует набор операций, которые вы, возможно, захотите выполнить на GFX::Material
, поэтому класс GFX::Material
должен реализовывать эти операции (Я не знаю, что это такое, но вот некоторые предположения):
//These can be automatically generated,
//but they are still part of the interface [
//Copy construct and assign
GFX::Material(GFX::Material const&);
GFX::Material& operator=(GFX::Material const&);
//Move construct and assign
GFX::Material(GFX::Material&&);
GFX::Material& operator=(GFX::Material&&);
//Destruct
GFX::~Material();
]
//Draw
void draw(Canvas& canvas, vec<2, float> posision);
//Stretch
void stretch(vec<2, float> scale);
//...
Теперь, чтобы настроить, как GFX :: Material реагирует на каждую из этих операций - дать ему параметризованный конструктор:
GFX::Material(/*Data to set up how I behave*/);
Теперь больше нет необходимости передавать указатели в ContentLoader
, GFX::Material
знает, как правильно копировать себя, перемещать себя и выполнять другие операции, которые зависят от его значения.
После этого ContentLoader
можно переписать следующим образом:
class ContentLoader
{
private:
std::map<std::string, GFX::Material> m_Materials;
typedef std::pair<std::string, GFX::Material> MTLPAIR;
public:
ContentLoader();
~ContentLoader();
void RegisterMaterial(GFX::Material mtl, std::string szName);
GFX::Material& GetMaterial(std::string const& szName);
};
Так как же на самом деле будет реализован GFX::Material
Судя по всему, вы ожидаете, что диапазон возможных вариантов поведения GFC::Material
будет сильно варьировать.Если это так, то, вероятно, было бы лучше реализовать его как объект, который содержит указатель на другой объект, который может содержать переменные данные и функции.Это можно реализовать с помощью наследования:
struct MaterialImplementaton {
//Copy:
virtual std::unique_ptr<MaterialImplementaton> clone() const = 0;
//Destroy:
virtual ~MaterialImplementaton() {}
//Draw
virtual void draw(Canvas& canvas, vec<2, float> posision) = 0;
//Stretch
virtual void stretch(vec<2, float> scale) = 0;
//...
};
Теперь вы можете передать unique_ptr<MaterialImplementaton>
в GFX::Material(/*Data to set up how I behave*/)
для настройки поведения.GFX :: Material будет хранить clone_ptr<MaterialImplementation>
и просто перенаправлять вызовы на MaterialImplementation
.
. Это всего лишь одна из многих возможных реализаций GFX::Material
.Важно то, что GFX::Material
может правильно содержать все операции, которые ему необходимо выполнить.