1

Тема: C++ Конструктор копіювання

Код ніби написав робочий, але вилітає помилка "Exception thrown: read access violation. this->data1 was nullptr.".

#include <iostream>
using namespace std;

class Myclass
{
public:
    int *data1;
    int data2;
public:
    int SIZE;

    Myclass (int size)
    {
;        data1 = new int [size];
        data2 = size;
        for (int i = 0; i < size; i++)
        {
            data1[i] = size;
        }

        cout << "Constructor = " << "data1 = " << *data1 << " " << "data2 = " << data2 << endl;
    }
    Myclass() = default;

    ~Myclass()
    {
        cout << "Destructor = " << "data1 = " << *data1 << " " << "data2 = " << data2 << endl;
        delete[] data1, data2;
    }
    Myclass(Myclass const& other)
    {
        data1 = new int [other.data2];
        for (int i = 0; i < other.data2; i++)
        {
            data2 = other.data1[i];
            *data1 = other.data1[i];
        }

        cout << "Copy-Constructor = " << "data1 = " << *data1 << " " << "data2 = " << data2 << endl;
    }

    int Input(int a=1)
    {
        a = SIZE;
        cin >> SIZE;
        return SIZE;
    }
    
};

Myclass* Obj;

class Pohidniy :public Myclass
{
public:

    Pohidniy(int a=0, int b=0)
    {
        
        a = *data1; b = data2;
        cout << "Class Pohidniy = " << "data1 = " << *data1 << " " << "data2 = " << data2 << endl;
    }
    

    int Dodavanya(int a, int b)
    {
        a = *data1; b = data2;
        int result;
        result = a + b;
        cout << "The result of Dodavanya is " << result << endl;
        return result;
    }
    int Vidnimanya(int a, int b)
    {
        a = *data1; b = data2;
        int result;
        result = a - b;
        cout << "The result of Vidnimanya is " << result << endl;
        return result;
    }
    int Mnojenya(int a, int b)
    {
        a = *data1; b = data2;
        int result;
        result = a * b;
        cout << "The result of Mnojenya is " << result << endl;
        return result;
    }
    void Check(int a=1, int b=1)
    {
        a = *data1; b = data2;
        cout << "What do you want to do?" << endl << "1) Dodavanya" << endl <<
            "2) Vidnimanya" << endl << "3) Mnojenya" << endl;
        char check;
        do
        {
            cin >> check;
        } while (check != '1' && check != '2' && check != '3');

        if (check == '1')
        {
            Dodavanya(*data1, data2);
        }
        else if (check == '2')
        {
            Vidnimanya(*data1, data2);
        }
        else
        {
            Mnojenya(*data1, data2);
        }
    }
};



int main()
{
    Obj = new Myclass();
    Obj->Input();
    int a;
    a = Obj->SIZE;
    Myclass first(a);
    Myclass second(first);
    
    /*int a;
    cin >> a;
    Myclass Obj(a);
    Myclass Obj2(Obj);*/
    Pohidniy pohidniy(2,3);
    pohidniy.Check();
}

2 Востаннє редагувалося koala (02.05.2022 13:22:17)

Re: C++ Конструктор копіювання

Тут помилка на помилці.
Конкретно ваша, як я розумію, пов'язана з тим, що Pohidniy - нащадок Myclass і, відповідно, містить його копію; але ви не ініціалізуєте поля data1 і data2, тому

a = *data1

створює помилку (бо data1 є nullptr і не підлягає розіменуванню).

Щоб далі коментувати, мені потрібне ваше завдання. Зауважу лише, що *data1 - це те саме, що data1[0]. Конструктор копіювання безглуздий.

Подякували: leofun01, QYQYA2

3

Re: C++ Конструктор копіювання

Моє завдання:
Клас комплексних чисел
Базовий клас (уявних чисел):
Конструктори: за замовчуванням, з параметрами та копіюванням.
Деструктор.
Функції: додавання;  віднімання;  множення на дійсне число;  виведення інформації на екран.
Похідний клас: комплексних чисел.

Конструктор копіювання вроді як записує нормально значення в *data1 і data2, але коли програма виходить с області базового класу Myclass, ці параметри чомусь стають нулями, раніше я виправляв цю помилку через глобальні змінні передаючи їм значення *data1 і data2, а потім в похідному класі використовував їх, але це протирічить моєму завданню.

4

Re: C++ Конструктор копіювання

Завдання одразу з помилкою, клас комплексних чисел не має бути похідним від класу уявних чисел. В теорії можна було б погратися в множинне наслідування, але це в цілому безглуздо.
Ну добре, яке завдання є - таке є. Отже, у вас є клас уявних чисел, який зветься... Myclass. Не Imaginary чи якось так, а Myclass. Дуже інформативно. Одразу зрозуміло, що Myclass - це уявне число.
І цей клас містить... два цілих числа і посилання на масив цілих чисел. Нащо? Уявне число - це звичайне число з множником i. Оскільки множник у всіх однаковий, то він реалізується в методах. Всі дані - одне число. Швидше за все - дійсне (float чи double). Все.
Далі у вас клас для комлексного числа. Клас комплексних чисел зветься... Pohidniy.  *WALL* Вас спеціально навчають одразу обфускований код писати, чи що? Клас комплексних чисел має бути, вочевидь, Complex.
Назвіть класи по-людськи, викидайте всі непотрібні дані, всю їхню обробку (яка все одно не працює) і буде у вас чистий і зручний для розуміння код.

Подякували: leofun01, QYQYA2

5

Re: C++ Конструктор копіювання

:D Жестяк)). Щось мені здається, що із завданням він також щось наплутав.

Подякували: leofun011

6

Re: C++ Конструктор копіювання

Завдання іменно так і написано, над назвами класів довго не думав, конструктор і конструктор копіювання взяв з відео SimpleCode  про конструктор копіювання, завдання я вообще не зрозумів з самого початку, я думав треба, щоб число вводилось через функцію базовго класу, потім конструктор копіювання копіює це число і записує його в іншу змінну базовго класу, потім похідний клас за допомгою своїх функцій робить дії над введеним і скопіюваним числом.

7 Востаннє редагувалося lucas-kane (02.05.2022 20:15:53)

Re: C++ Конструктор копіювання

Добре. Поясність, що значить:

Прихований текст
// 1. 
    Pohidniy(int a=0, int b=0)
    {        
        a = *data1; b = data2; // А саме, що відбувається у цих рядках

 /* ... */

    int Dodavanya(int a, int b)
    {
        a = *data1; b = data2; // і тут

/* ... */

    int Vidnimanya(int a, int b)
    {
        a = *data1; b = data2; // і тут також 


/* ... */

    int Mnojenya(int a, int b)
    {
        a = *data1; b = data2; // .. ну і....?????

/* ... */

    void Check(int a=1, int b=1)
    {
        a = *data1; b = data2; // )) ????

/* ... */

// 2.

    int Input(int a=1)
    {
        a = SIZE; // навіщо потрібна змінна а, якщо вона ніде не використовується?????!!!!
        cin >> SIZE;
        return SIZE;
    }

Якщо ви не зрозуміли завдання, тоді почніть із вивчення, що таке комплексне число. Хоча по вашому коду можна припустити, що і лекції з ООП вам також потрібно підтягнути. Код м'яко кажучи безглуздий?

Подякували: QYQYA, leofun012

8

Re: C++ Конструктор копіювання

в цих рядка я присвоюю параметрам функцій значення параметрів *data1 і data2 класу Myclass, але там нулі тому, що потрібний об'єкт класу Myclass, і я не знаю як його туди поставити, щоб передати потрібні мені значення змінних

9

Re: C++ Конструктор копіювання

QYQYA написав:

в цих рядка я присвоюю параметрам функцій значення параметрів *data1 і data2 класу Myclass

Нащо? Нащо вам параметри, які ви одразу затираєте? Якщо вам не потрібно нічого приймати з-за меж функції - просто видаліть параметри.

QYQYA написав:

але там нулі тому, що потрібний об'єкт класу Myclass, і я не знаю як його туди поставити, щоб передати потрібні мені значення змінних

Щоб що передати куди? У вас, схоже, серйозні проблеми з розумінням функцій, вам дуже зарано класи вивчати.

От є у вас такий метод:

int Vidnimanya(int a, int b)

Це означає, що якщо x - об'єкт типу Pohidniy (та перейменуйте його врешті-решт!), то можна викликати

x.Vidnimanya(2,3)

а можна

x.Vidnimanya(6,10)

але ці виклики будуть далі працювати абсолютно однаково, бо a та b будуть одразу затерті значеннями всередині. То нащо вам узагалі ті параметри?

Подякували: QYQYA1

10

Re: C++ Конструктор копіювання

Мені потрібно передати значення *data1 і data2 в функції класу Pohidniy, потім вивести результат.

11

Re: C++ Конструктор копіювання

QYQYA написав:

Мені потрібно передати значення *data1 і data2 в функції класу Pohidniy, потім вивести результат.

По-перше, я не бачу, яким чином із завдання випливає, що вам це потрібно.
По-друге, всі публічні змінні класу доступні в нащадках. Власне, якби ви не отримали доступу до них, то

a = *data1;

не скопілювалося б.

Подякували: QYQYA1

12

Re: C++ Конструктор копіювання

Можна в функціях написати параметри за замовчуванням, щоб при виклику не вводити в дужках нічого. Я якраз не розумію де стираються значення data1 і data2, деструктор в момент передачі значень з базового класу в похідний ще не включається.

13

Re: C++ Конструктор копіювання

QYQYA написав:

в момент передачі значень з базового класу в похідний

Немає такого моменту.
Будь ласка, почистьте код від зайвих речей і дайте нормальні назви ідентифікаторам, а потім розбирайтеся з завданням. З таким кодом дуже важко працювати - через що, зокрема, у вас і проблеми.

Подякували: QYQYA1

14

Re: C++ Конструктор копіювання

Поясніть мені будь-ласка в чому де тут помилка.

#include <iostream>
using namespace std;

class Base
{
protected:
    int *DATA1;
    int result;
public:
    Base(int a)
    {
        a = *DATA1;
    }
    Base() = default;

    int InputData(int a=0)
    {
        
        cin >> a;
        a = *DATA1;
        return a;
    }
    int Addition(int a=0, int b=0)
    {
        a = *DATA1; b = *DATA1;
        
        result = a + b;
        return result;

    }
};


class Hereditary : public Base
{
public:
    void SHOW()
    {
        cout << "Result = " << result << endl;
    }


};

Base* obj1;

int main()
{
    obj1 = new Base;
    obj1->InputData();
    obj1->Addition();
    Hereditary OBJ;
    OBJ.SHOW();
}

15 Востаннє редагувалося koala (03.05.2022 13:37:50)

Re: C++ Конструктор копіювання

Тут легше пояснити, де немає помилки - у рядку #include.

    int InputData(int a=0)
    {
//у цьому місці DATA1 дорівнює nullptr (бо інше не встановлювалося), а a - переданому аргументу, наприклад, 0
        cin >> a;
//у цьому місці a дорівнює введеному значенню. Нащо ви 0 передавали? Він все одно тут перезапишеться
        a = *DATA1;
//а сюди виконання не дійде, бо ви спробували прочитати те, що знаходится за адресою DATA1, тобто nullptr, і записати його в a
//нащо ви a вводили, якщо хочете його перезаписати? І чим перезаписати - значенням з невстановленої адреси в пам'яті?
        return a;
    }

Цей метод приймає параметр і перезаписує цей параметр спершу введеним числом, а потім невизначеним значенням. Нащо ви це робите? От в чому сенс? Ви не знаєте, як присвоєння працює? Чи розіменування? Будь ласка, вивчить основи, а потім переходьте до ООП. Там немає нічого суперскладного, але ви зараз як людина, що не дуже добре вивчила таблицю додавання і намагається виконати завдання на множення дробів.

Подякували: QYQYA, leofun012

16

Re: C++ Конструктор копіювання

Тепер значення передається нормально в класі Base, але все рівно виводячи result через SHOW функцію класу Hereditary виводить 0, коли через ту саму функцію тільки класу Base виводить то, що треба, виходить, я не можу вивести значення якогось параметра базового класу через функцію похідного класу викликаючи її через об'єкт похідного класу.

#include <iostream>
using namespace std;

class Base
{
protected:
    int data1;
    int *DATA1=&data1;
    int result;
public:
    Base(int a, int b)
    {

    }
    Base() = default;

    int InputData(int a=0)
    {
        cin >> a;
        *DATA1 = a;
        return *DATA1;
    }
    int Dodavanya(int a=0, int b=0)
    {
        a = *DATA1; b = *DATA1;
        
        result = a + b;
        return result;

    }
    void SHOW()
    {
        cout << "Result = " << result << endl;
    }
};

class Hereditary : Base
{
public:
    void SHOW()
    {
        cout << "Result = " << result << endl;
    }


};

Base* obj1;

int main()
{
    obj1 = new Base;
    obj1->InputData();
    obj1->Dodavanya();
    Hereditary OBJ;
    OBJ.SHOW();
    obj1->SHOW();
}

17

Re: C++ Конструктор копіювання

А ви не робите жодних операцій із OBJ.result. Чому воно має змінитися?
І чому ви не можете написати

    void InputData()
    {
        int a;
        cin >> a;
        *DATA1 = a;
    }

чи навіть просто

    void InputData()
    {
        cin >> *DATA1;
    }

От нащо вам той аргумент?

Подякували: QYQYA1

18

Re: C++ Конструктор копіювання

Переписав майже всьо.

#include <iostream>
using namespace std;

class Base
{
public:
    int DATA1;
    int DATA2;
public:
    Base(int a, int b)
    
    {DATA1 = a; DATA2 = b;}
    Base() = default;
    
    ~Base(){}

    Base(Base const& Obj1)
    {DATA1 = Obj1.DATA1; DATA2 = Obj1.DATA2;}
    
    void Input()
    {cin >> DATA1; cin >> DATA2;}
};

class Hereditary : Base
{
protected:
    int DATA1;
    int DATA2;
public:
    Hereditary(int a, int b){}
    Hereditary() = default;
    
    ~Hereditary(){}

    int Addition(int a, int b)
    {
        int result;
        result = a + b;
        cout << "The result of Addition is " << result << endl;
        return result;
    }
    int Subtraction(int a, int b)
    {
        int result;
        result = a - b;
        cout << "The result of Subtraction is " << result << endl;
        return result;
    }
    int Multiplication(int a, int b)
    {
        int result;
        result = a * b;
        cout << "The result of Multiplication is " << result << endl;
        return result;
    }
    int Check(int a, int b)
    {
        DATA1 = a; DATA2 = b;
        cout << "What do you want to do?" << endl << "1) Addition" << endl <<
            "2) Subtraction" << endl << "3) Multiplication" << endl;
        char check;
        do
        {
            cin >> check;
        } while (check != '1' && check != '2' && check != '3');

        if (check == '1')
        {
            Addition(a, b);
        }
        else if (check == '2')
        {
            Subtraction(a, b);
        }
        else
        {
            Multiplication(a, b);
        }
        return a, b;
    }
};

Base* Obj;

int main()
{
    Obj = new Base();
    Obj->Input();
    int a, b;
    a = Obj->DATA1;
    b = Obj->DATA2;
    Hereditary Obj2;
    Obj2.Check(a,b);
}

19

Re: C++ Конструктор копіювання

Наскільки я зрозумів, неможливо передати скопійовані параметри одного об'єкту якогось класу, іншому об'єкту другого класу, якщо можна, в мене би появилась можливість реалізувати передачу без додаткових змінних в main'і.

20 Востаннє редагувалося lucas-kane (03.05.2022 18:48:27)

Re: C++ Конструктор копіювання

        }
        return a, b;  //  Що ви тут хочете повернути?
    }
};

Base* Obj;

На якому курсі ви навчаєтесь? і що взагалі ваша програма має робити? Це якийсь калькулятор? До умови вашої задачі вона ніяким боком!

Подякували: QYQYA, leofun012