Search code examples
c++deleted-functions

Trying to locate a deleted function


Messing around in C++ for class and came across a error stating that i was trying to reference a deleted function. Here is the error

C2280(Test &Test::operator = (const Test& : attempting to reference a deleted function).

Here is my code:

#include "pch.h"
#include <iostream>

using namespace std;

class Test {
public:
    int size;
    double* array;
public: 
    Test();
    Test& operator=(Test&& a);
    Test(int sizeArg) {
        size = sizeArg;
        array = new double[size];
    }
    Test(Test&& arg) {
        size = arg.size;
        array = arg.array;
        arg.size = 0;
        arg.array = nullptr;
    }
    ~Test()
    {
        if (array != nullptr) {
            delete[]array;
        }
    }
};

int main()
{
    Test outTest;
    int x = 1;
    //Wont work since looking for a deleted function
    if (x = 1) {
        Test arg(200000000);
        outTest = arg;
    }
    cout << outTest.array;
}

The problem is in the main() on the equal sign.


Solution

  • You should get an error along these lines:

    constexpr Test& Test::operator=(const Test&)’ is implicitly declared as deleted because ‘Test’ declares a move constructor or move assignment operator

    This is a good thing, because the default copy assignment operator would have done a terrible job. It would have copied your pointer - and you would have ended up with two instances both claiming to own the data. Both would try to delete[] it later - with undefined behaviour as a result.

    You should probably implement all 5 member functions mentioned in The rule of three/five/zero.

    Example:

    #include <algorithm>
    #include <iostream>
    #include <utility>
    
    class Test {
    public:
        int size;
        double* array;
    public: 
        Test() : 
            size(0),
            array(nullptr)                    // make sure the default constructed array
                                              // is set to nullptr
        {}
        Test(int sizeArg) :
            size(sizeArg),
            array(new double[size]{})         // zero initialize the array
        {}
        // rule of five:
        Test(const Test& arg) :               // copy ctor
            size(arg.size),
            array(new double[size])
        {
            std::copy(arg.array, arg.array+size, array);
        }
        Test(Test&& arg) :                    // move ctor
            size(arg.size),
            array(std::exchange(arg.array, nullptr)) // get pointer from arg and give nullptr
                                                     // to arg
        {}
        Test& operator=(const Test& arg) {    // copy assignment operator
            Test tmp(arg);                    // reuse copy constructor
            std::swap(*this, tmp);            // let "tmp" destroy our current array
            return *this;
        } 
        Test& operator=(Test&& arg) {         // move assignment operator 
            size = arg.size;
            std::swap(array, arg.array);      // let the other object delete our current array
            return *this;
        }   
        ~Test() {
            delete[] array;                   // no "if" needed, it's ok to delete nullptr
        }
    };
    
    int main()
    {
        Test outTest;
        int x = 1;
    
        if(x==1) {                           // use == when comparing for equality
            Test arg(2);
            outTest = arg;
        }
        std::cout << outTest.array;
    }