Привет!
Я пытаюсь найти некоторые оптимальные решения в шаблонах кодирования C++, и это один из моих вопросов, связанных с игровым движком.
Взгляните на объявление игрового объекта (я удалил почти все, что не имеет отношения к вопросу).
// Abstract representation of a game object
class Object :
public Entity,
IRenderable, ISerializable {
// Object parameters
// Other not really important stuff
public:
// @note Rendering template will never change while
// the object 'lives'
Object(RenderTemplate& render_template, /* params */) : /*...*/ { }
private:
// Object rendering template
RenderTemplate render_template;
public:
/**
* Default object render method
* Draws rendering template data at (X, Y) with (Width, Height) dimensions
*
* @note If no appropriate rendering method overload is specified
* for any derived class, this method is called
*
* @param Backend & b
* @return void
* @see
*/
virtual void Render(Backend& backend) const {
// Render sprite from object's
// rendering template structure
backend.RenderFromTemplate(
render_template,
x, y, width, height
);
}
};
Вот также объявление интерфейса IRenderable:
// Objects that can be rendered
interface IRenderable {
/**
* Abstract method to render current object
*
* @param Backend & b
* @return void
* @see
*/
virtual void Render(Backend& b) const = 0;
}
и образец реального объекта, полученного из Object
(с серьезными упрощениями :)
// Ball object
class Ball : public Object {
// Ball params
public:
virtual void Render(Backend& b) const {
b.RenderEllipse(/*params*/);
}
};
Что я хотел получить, так это возможность иметь какую-то стандартную функцию, которая рисовала бы спрайт для объекта (это Object::Render
), если нет соответствующей перегрузки.
Таким образом, у объекта могут быть объекты без метода Render(...)
, и если вы попытаетесь их визуализировать, будет вызван этот механизм рендеринга спрайтов по умолчанию. Кроме того, могут быть специализированные объекты, определяющие собственный способ отображения.
Я думаю, что такой способ ведения дел довольно хорош, но вот что я не могу понять: есть ли способ отделить реализацию "обычных" методов объектов (таких как Resize(...)
или Rotate(...)
) от их реализации рендеринга?< /сильный>
Потому что, если все сделать так, как описано ранее, общий файл .cpp, который реализует любой тип объекта, обычно смешивает реализацию методов Resize(...)
и т. д. и этот метод virtual Render(...)
, и это кажется беспорядком. Я вообще-то хочу, чтобы процедуры рендеринга объектов были в одном месте, а их "логическая реализация" - в другом.
Есть ли способ это сделать (может быть, альтернативный шаблон, трюк или подсказка), или все эти полиморфные и виртуальные вещи отстойны с точки зрения размещения кода?
new
в реальном коде. То, что я делаю сейчас (только для тестирования и создания прототипа), в целом похоже на созданиеBall ball
и вызовball.Render(backend);
. Я понимаю, что в этой ситуации мне даже не нужен этотvirtual
материал, но я думаю, что скоро я сделаю что-то вродеstd::vector<IRenderable*>
, и тогда мне действительно понадобится виртуальный деструктор. В любом случае, спасибо за указание :) - person M. Williams   schedule 22.04.2010