Как правильно сделать глубокую копию для абстрактных классов?

Я работаю над системой столкновений, для которой мне нужно скопировать коллайдеры сущностей.

Я делаю систему такой, что мне не нужно задавать в камне то, как я хочу обрабатывать столкновения (и я, вероятно, начну использовать 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 =, просто не сможет связать.

Другие вопросы по тегам