Как правильно сделать глубокую копию для абстрактных классов?
Я работаю над системой столкновений, для которой мне нужно скопировать коллайдеры сущностей.
Я делаю систему такой, что мне не нужно задавать в камне то, как я хочу обрабатывать столкновения (и я, вероятно, начну использовать AABB, но могу перейти на SAT), но мне нужно будет делать глубокие копии коллайдеров, в зависимости от того, что я буду использовать.
с одной стороны, глубокое копирование является обязательным требованием, и, похоже, именно к нему следует обращаться.
С другой стороны, мой collidable
не должно быть ничего, кроме интерфейса, поэтому не должно быть никаких причин не делать это чисто виртуальным.
поэтому я начал писать так:
class collidable
{
public:
virtual collidable& operator= (collidable other)=0;
};
Но я не могу скопировать конструкцию collidable
потому что это чисто виртуальный.
Обратите внимание, что в рамках одной и той же программы я никогда не буду использовать более одного алгоритма коллизии одновременно, поэтому не будет конфликта методов.
Я действительно не знаю, что я делаю неправильно, если это касается дизайна или технической стороны, поэтому я полностью открыт для предложений.
Как я могу заставить класс, производный от collidable, реализовать operator=?
1 ответ
Возможно, вы путаете использование интерфейса с реализацией класса. Это вероятно потому, что чисто виртуальные классы - это то, как C++ определяет интерфейс.
С вашей реализацией вам не повезет, потому что вы получите следующие типы сценариев:
class A : public collidable
{
...
}
class B : public collidable
{
...
}
int main (int argc, char** argv)
{
collidable *A = new A ();
collidable *B = new B ();
*A = *B;
...
}
Это было бы очевидно проблемой. Что вы хотите сделать, это определить общие операции, которые будут применяться к каждой реализации различных алгоритмов в вашем интерфейсе. Назначение, скорее всего, не будет одной из этих общих операций, потому что назначение должно быть выполнено с двумя одинаковыми типами.
Если вы когда-либо использовали только один тип алгоритма, как вы заявили, создайте классы-потребители для каждого класса классов. Затем, когда вы работаете с реализациями алгоритма и вызываете operator = для каждого класса алгоритма, компилятор должен принудительно вызывать operator = для каждой реализации алгоритма во время компоновки. Реализация алгоритма, в которой не определен operator =, просто не сможет связать.