Search code examples
c++interfacecopy-and-swap

How to correctly make deep copy for abstract classes?


I'm working on a collision system for which I need to copy the colliders of entities.

I make the system such as I don't have to set in stone how I want to handle collision, (and I will start using AABB likely, but might change to SAT) but I will need to make deep copy of colliders whichever algo I will use.

on one hand, deep copy is a requirement, and the copy and swap idiom seemed to be what I should go to.

On the other hand, my collidable doesn't need to be anything other than an interface, so there should be no reason not to do it pure virtual.

therefore, I began by writing this :

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

But I can't copy construct collidable because it is pure virtual.

Note than within a same program, I will never use more than one algorithm of collision at the same time, so there wont be conflict of methods.

I don't really know what I'm doing wrong, if its the design side or the technical side, so I'm completely open to suggestions.

How can I force class derived of collidable to implement operator= ?


Solution

  • You're probably confusing the use of an interface with a class implementation. This is likely because pure virtual classes are how C++ defines an interface.

    With your implementation you're not going to have much luck because you'll get these types of scenarios:

    class A : public collidable
    {
      ...
    }
    
    class B : public collidable
    {
      ...
    }
    
    int main (int argc, char** argv)
    {
        collidable *A = new A ();
        collidable *B = new B ();
    
        *A = *B; 
        ...
    }
    

    This would obviously be a problem. What you want to do is define generic operations that would apply to each different algorithm implementation in your interface. Assignment would likely not be one of those generic operations because assignment needs to be done with two of the same types.

    If you are only ever using one algorithm type as you stated, make the consumer classes of each algorithm class templated classes. Then when you're operating on your algorithm implementations and call operator= on each algorithm class, the compiler should force operator= for each algorithm implementation during linking. An algorithm implementation that doesn't have operator= defined simply won't be able to link.