Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

What is the purpose of deleting copy constructor and assignment operator for RAII(C++)?

+3 votes
asked Dec 18, 2021 by Areeb Sherjil (1,960 points)
I understand Resource Acquistion Is Initialization(RAII) and why it is to be used.

Say you wanted to dynamically allocate memory and use the destructor to tidy up resources. An article states:

" The trick to avoid resource leaks is then that, by default, the destructor of that object makes sure the resource is always freed. Let’s create a simple RAII class to demonstrate how this idiom works:

class DoubleArrayRAII final {

public:

DoubleArrayRAII(size_t size) : m_resource{ new double[size] } {}

~DoubleArrayRAII() {

std::cout << "Freeing memory..." << std::endl;

delete[] m_resource; }

// Delete copy constructor and assignment operator

DoubleArrayRAII(const DoubleArrayRAII&) = delete;

DoubleArrayRAII& operator=(const DoubleArrayRAII&) = delete;

"

Question why are we deleting copy constructor and assignment operator. Isn't the destructor freeing up memory ?

1 Answer

0 votes
answered Dec 19, 2021 by Peter Minarik (87,340 points)
selected Dec 19, 2021 by Areeb Sherjil
 
Best answer

Let's consider what would happen if you don't disable the default copy constructor and assignment operators: they are automatically implemented as a shallow copy.

This means that the values of fields in your class are copied. For pointers, it means the pointers are copied, not duplicated  (the memory address itself is copied, not the pointed value), i.e. both the original and the copy will point to the same memory address. When the destructor tries to free the resources (delete) it will do it twice, the second causing a runtime error of double freeing the resource.

In the below example m_resouirce will be double freed.

#include <iostream>

class DoubleArrayRAII final
{
private:
    double * m_resource;
    
public:
    DoubleArrayRAII(size_t size) : m_resource { new double[size] } { }
    ~DoubleArrayRAII()
    {
        std::cout << "Freeing memory..." << std::endl;
        delete[] m_resource;
    }

    // Delete copy constructor and assignment operator
    //DoubleArrayRAII(const DoubleArrayRAII&) = delete;
    //DoubleArrayRAII& operator=(const DoubleArrayRAII&) = delete;
};

int main()
{
    DoubleArrayRAII a(5);
    DoubleArrayRAII b = a; // Double free when released
    DoubleArrayRAII c(a);  // Double free when released
    
    return 0;
}

I hope this helps.

Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...