Удаление экземпляра класса

В main.cpp создал экземпляр класса и динамически выделил под него память.

Rect*   pR = new Rect(1,2,1,2);

Создал деструктор

    Rect::~Rect()
    {
        delete pR;
    }

Выдаёт ошибку: " pR не определён в классе".

Объявил класс

    class Rect
    {
        int m_left, m_right, m_top, m_bottom;// объявили переменные
        
        public:
    
        //---------------------------------конструкторы----------------------------------------------
    
        Rect(); // явно переопределили дефолтовый конструктор без параметров
        
        Rect(int l, int r, int t, int b) // создали конструктор с параметрами
        {
            m_left = l;
            m_right = r;
            m_top = t;
            m_bottom = b;
        }
    
        Rect(const Rect& nov); // конструктор копирования
    
        ~ Rect(); // деструктор
    
        //--------------------------------методы------------------------------------------------------
    
        void Sec();                                     // проверка введенных данных
        void Print();                                   // печать
    
        int InflateRect(int a, int b, int c, int d);    // раздвигает стороны прямоугольника от центра
        int InflateRect(int z, int v);
        int InflateRect(int a);
    
        void SetAll(int a, int b, int c, int d);        // присваиваем значения переменным класса
        int GetAll();
        int GetRect_left();
        int GetRect_right();
        int GetRect_top();
        int GetRect_bottom();
    
        Rect BoundingRect(Rect r1, Rect r2);

Определил конструкторы и деструктор.

Rect::Rect()// конструктор без параметров
{
    m_left = 0;
    m_right = 0;
    m_top = 0;
    m_bottom = 0;
}

Rect::Rect(const Rect& nov)// конструктор копирования
{
    m_left = nov.m_left;
    m_right = nov.m_right;
    m_top = nov.m_top;
    m_bottom = nov.m_bottom;
    Sec();
}

Rect::~Rect()
{
    //std::cout << "Удаляем класс" << std::endl;
    //delete m_left;
}

В мейне создал экземпляры класса

    //Задание 5. Когда вызываются конструкторы и деструкторы.
    //Объявите и определите
    //явный деструктор класса. Поставьте остановы в 
    //конструкторе (конструкторах) и деструкторе. Определите: когда для
    //каждого из объектов вызывается конструктор, а когда - деструктор?
    {// вызывается конструктор без параметров r1 в прологе
        Rect r1;
        Rect*   pR = new Rect(1,2,1,2); //вызывается конструкторс с параметрами 
        {
            Rect r2(r1);// вызывается конструктор копирования 
            Rect arRect[2];//вызывактся по умолчанию
            for(int i=0; i<3; i++)
            {
                static Rect r3 (i,i,i,i) ;// конструктор вызывается при перво выполнении программы в прологе
                Rect r4(*pR); // вызывается конструктор копирования
                Rect r5(i,i,i,i);//вызывается конструкторс с параметрами 
            }// вызывается деструктор для r5,r4
        }// вызывается деструктор для r2,arRect

        delete pR;//вызывается деструктор для pR
        stop
    }//вызывается деструктор для  r1, r3    

Ответы (1 шт):

Автор решения: HolyBlackCat

Вам вообще не нужен ни деструктор, ни копирующий конструктор.

new и delete здесь тоже не нужны. Вместо Rect* pR = new Rect(1,2,1,2); пишите Rect pR(1,2,1,2);.

В комментариях предложили писать ~Rect() = default; вместо отсутсвия деструктора, но это может создать проблемы (именно для этого класса не создаст, но все равно привычка плохая). Если вам достаточно пустого/default деструктора, то не надо писать деструктор вообще.


Почему плохо писать пустой деструктор просто так? Потому что если вы пишете любой деструктор, компилятор перестает генерировать перемещающий конструктор и оператор присваивания.

Это втихую заменит все перемещения вашего класса на копирования, если его вообще можно скопировать. Если скопировать нельзя, то класс перестанет быть перемещаемым. Пример:

#include <memory>
#include <utility>

struct A
{
    std::unique_ptr<int> p;

    // ~A() {}
    // ~A() = default;
};

int main()
{
    A x;
    A y = std::move(x);
}

Это компилируется. Если раскомментировать любой из деструкторов, перестает.

Чтобы этого не происходило, в дополнение к деструктору нужно объявить как =default перемещающие операции (и копирующие тоже, если они нужны, потому что иначе они пропадут из-за объявления перемещающих).

→ Ссылка