MAXON_OPERATOR_MOVE_ASSIGNMENT and virtual destructor



  • Using the R19 SDK I had no problem with following piece of code.
    (omitted the CopyFrom implementation, needed for support in arrays)

    
    class Test_base
    {
    	MAXON_DISALLOW_COPY_AND_ASSIGN(Test_base);
    
    public:
    
    	Test_base() {}
    	explicit Test_base(const Int32& value) : mValue(value) {}
    	virtual ~Test_base() {}
    
    	// provide move constructor and move assignment operator
    	Test_base(Test_base&& src) : mValue(std::move(src.mValue)) {}
    	MAXON_OPERATOR_MOVE_ASSIGNMENT(Test_base);
    
    private:
    	Int32 mValue;
    };
    

    Migrating it to R20, however, I get:

    error C2338: MAXON_OPERATOR_MOVE_ASSIGNMENT can't be used for classes with virtual functions.
    

    Since this is a base class where derived classes will add their own members upon I need the destructor to be virtual. So, how do I go about resolving this issue?

    If I don't provide the move assignment operator then, obviously, I get the following compiler issue for a Test_derived class derived from Test_base:

    error C2248: 'Test_derived::operator =': cannot access private member declared in class 'Test_derived'
    


  • Hi Daniel,

    with regard to your question, as pointed out in our documentation, the MAXON_OPERATOR_MOVE_ASSIGNMENT macro can't be used for classes with virtual functions for the sake of safety.
    The reason is: Because the created move assignment operator would invoke the constructor, the vtable pointer of the
    object would be changed if one accidentally used the assignment operator of a base class for an object of a derived class.

    Since R20, the static_assert became part of the API and that was the reason why this prevented you to easily port the code.

    What you are supposed to do is instead to manually write the assignment operator like:

    Test_base& operator =(Test_base&& src)
    {
      mValue = std::move(src.mValue);
      return *this;
    }
    

    Best, Riccardo



  • I am still a C++ dinosaur, and particularly not experienced with the move operator.
    So thanks for pointing out the need for the manually written assignment operator.
    Together with the already implemented move constructor I had, I now more clearly see the point.