С++ копировать конструкторы и деструкторы

Я изучаю конструкторы и деструкторы в С++; Помоги мне понять мои ошибки, даже если они глупы...

ВОТ код, который я написал для выполнения сложения с использованием классов в С++; Это создает два слагаемых типа datatype num и использует конструктор sum() для выполнения суммы двух чисел; Однако, когда все шло хорошо, я наткнулся на создание конструктора копирования для num , (хотя и не обязательно, но все же для практики)... без динамического объекта класса sum невозможно все равно запустите код (без удаления конструктора копирования)... Помогите мне улучшить мой код и мои ошибки в приведенном ниже коде; Также я хочу знать, как использовать конструктор копирования в этой программе; проблема в том, что в деструкторе операция удаления выполняется несколько раз для одного и того же участка памяти (я полагаю)

Вот мой код

#include<iostream>
#include<new>
using namespace std;
class num
{
public:
    int *a;
    num(int x)
    {
        try
        {
            a=new int;
        }
        catch(bad_alloc xa)
        {
            cout<<"1";
            exit(1);
        }
        *a=x;
    }
    num(){  }
    num(const num &ob)
    {
        try
        {
            a=new int;
        }
        catch(bad_alloc xa)
        {
            cout<<"1''";
            exit(2);
        }
        *a=*(ob.a);
    }
    ~num()
    { 
        cout<<"Destruct!!!";
        delete a;
    }
};


class sum:public num
{
 public:
     int add;
     sum(num n1,num n2)
     {
         add=*(n1.a)+*(n2.a);
     }
     int getsum()
     {
         return add;
     }
};

int main()
{
    num x=58;
    num y=82;
    sum *s=new sum(x,y);
    cout<<s->getsum();
    delete s;
    return 0;
}

person Arijit Dey    schedule 05.07.2018    source источник
comment
Для проверки кода вы можете посетить CodeReview Stackexchange.   -  person UnholySheep    schedule 05.07.2018
comment
num(){ } это крайне неправильно. Вы не можете оставить элемент данных указателя неинициализированным.   -  person n. 1.8e9-where's-my-share m.    schedule 05.07.2018
comment
Почему sum нужно наследовать от num? sum(num n1,num n2) предпочитают вместо этого брать const num&. sum(const num& n1, const num& n2)   -  person Wander3r    schedule 05.07.2018
comment
Я не вижу необходимости, чтобы num содержал int *, а не только int. Или чтобы он существовал вообще. Просто оперируйте ints   -  person Caleth    schedule 05.07.2018


Ответы (1)


Я могу что-то упустить - слишком долго не использовал new/delete, но пытался исправить все, что заметил.

P.S. всегда используйте умные указатели.

#include <iostream>
#include <exception>
#include <new>

using namespace std;

int* allocate(const char* err_msg, int exit_code)
{
    int* a = nullptr;
    try
    {
        a = new int;
    }
    catch (bad_alloc&)
    {
        cout << err_msg << endl;
        exit(exit_code);
    }
    return a;
}

class num
{
    int* a = nullptr; // always should be initialized here

public:
    num() noexcept : a(nullptr) // or here
    {}

    /*explicit*/ num(int x) : a(allocate("1", 1))
    {
        *a = x;
    }

    num(const num& ob) : a(allocate("1''", 2))
    {
        *a = *(ob.a);
    }

    // rule of zero/three/five
    // default copy assignment will copy pointer and one int will be leaked and one will be deleted twice
    num& operator =(const num& ob)
    {
        if (&ob == this)
        {
            return *this;
        }

        *a = *(ob.a);
        return *this;
    }

    ~num()
    { 
        cout << "Destruct!!!";
        delete a;
        a = nullptr; // usefull for debug
    }

    int value() const
    {
        if (a == nullptr)
        {
            throw runtime_error("a == nullptr");
        }
        return *a;
    }
};

class sum
{
    int add = 0;

public:
    sum(const num& n1, const num& n2)
    {
        add = n1.value() + n2.value();
    }

    int getsum() const
    {
        return add;
    }
};

int main()
{
    const num x = 58;
    const num y = 82;
    const sum* s = new sum(x, y);
    cout << s->getsum() << endl;
    delete s;
    return 0;
}
person wtom    schedule 05.07.2018
comment
Спасибо за вашу помощь; - person Arijit Dey; 06.07.2018
comment
Еще один; так как я новичок в конструкторах и исключениях, не могли бы вы объяснить строки num() noexcept: a(nullptr) и правило 0 3 и 5? - person Arijit Dey; 06.07.2018
comment
Во время компиляции вылезают десятки ошибок; Я не могу отлаживать эти ошибки - person Arijit Dey; 06.07.2018
comment
@ArijitDey Какой компилятор вы используете? Вот объяснение правила 0/3/5: en.wikipedia. org/wiki/Правило_трех_(C%2B%2B_programming) - person wtom; 09.07.2018
comment
@ArijitDey num() noexcept: a(nullptr) — это конструктор по умолчанию, инициализирующий a значением 0. - person wtom; 09.07.2018