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

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

Я создаю систему таким образом, что мне не нужно закладывать в камне, как я хочу обрабатывать столкновения (и я, скорее всего, начну использовать AABB, но могу перейти на SAT), но мне нужно будет сделать глубокую копию коллайдеров, какой бы алгоритм я ни использовал. буду использовать.

с одной стороны, глубокое копирование является обязательным требованием, и идиома копировать и подкачивать казалась тем, к чему я должен был прибегнуть.

С другой стороны, мой collidable не должен быть ничем иным, как интерфейсом, поэтому не должно быть никаких причин не делать его чисто виртуальным.

поэтому я начал с того, что написал следующее:

class collidable
{
  public:
    virtual collidable& operator= (collidable other)=0;
};

Но я не могу скопировать конструкцию collidable, потому что она чисто виртуальная.

Обратите внимание, что в одной и той же программе я никогда не буду использовать более одного алгоритма коллизии одновременно, поэтому конфликта методов не будет.

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

Как я могу заставить класс, производный от collidable, реализовать operator= ?


person Pierre-Antoine Guillaume    schedule 15.04.2017    source источник
comment
Возможный дубликат конструктора копирования: глубокое копирование абстрактного класса   -  person Joseph Thomson    schedule 15.04.2017
comment
Вообще говоря, вы не стали бы смешивать полиморфную иерархию с семантикой значений. Если вам нужна полиморфная иерархия, отключите копирование и перемещение построения (или используйте их только в final классах иерархии), потому что базовый класс не будет знать, как это сделать. Предоставьте виртуальную функцию, такую ​​​​как clone(), в базовом классе, чтобы разрешить создание копий на основе указателя на базу, если вы хотите поддерживать эту функциональность.   -  person M.M    schedule 16.04.2017
comment
в общем, это то, что я хочу сделать, за исключением того, что я думаю, что оператор = действительно лучше представляет семантику клона. Заставить его вести себя так, как это делают целые, мне казалось, что это правильный путь. С другой стороны, это действительно создает впечатление (у пользователя), что одному производному можно присвоить значение другого производного. И это плохая идея сама по себе. Я понимаю, что вы имеете в виду, теперь   -  person Pierre-Antoine Guillaume    schedule 16.04.2017


Ответы (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; 
    ...
}

Очевидно, это будет проблемой. Что вы хотите сделать, так это определить общие операции, которые будут применяться к каждой реализации алгоритма в вашем интерфейсе. Присваивание, скорее всего, не будет одной из таких универсальных операций, потому что присваивание необходимо выполнять с двумя одинаковыми типами.

Если вы когда-либо используете только один тип алгоритма, как вы указали, создайте потребительские классы каждого класса шаблонных классов алгоритма. Затем, когда вы работаете со своими реализациями алгоритма и вызываете оператор = для каждого класса алгоритма, компилятор должен принудительно использовать оператор = для каждой реализации алгоритма во время компоновки. Реализация алгоритма, в которой не определен оператор =, просто не сможет связать.

person Community    schedule 16.04.2017
comment
Ах, вы имеете в виду использование шаблона в качестве интерфейса, чтобы заставить пользователя (меня) реализовывать решения, как в том, что должно было быть в концепциях? - person Pierre-Antoine Guillaume; 16.04.2017
comment
Понятия — это операции, выполняемые вашим алгоритмом. - person ; 17.04.2017