Тема: Яким повинен бути конструктор класу?

#include<iostream>

class matrytsja
{   private:
        int x,y;
        int **m;
    public:
        matrytsja(int _x=0, int _y=0) : (x=_x,  y=_y)
        {
                m=new int*[x];
                for (int i=0; i<x; i++)
                m[i]=new int [y];
        }

        ~matrytsja()
        {
            for(int i=0; i<x; i++)
            delete []  m[i];

            delete []  m;
        }


};

int main()
{
    std::cout << "Y" << std::endl;
    matrytsja m1(50,100);

return 0;
}

||=== Build: Debug in matrytsja (compiler: GNU GCC Compiler) ===|
G:\Heloworld\matrytsja\matrytsja.cpp||In constructor 'matrytsja::matrytsja(int, int)':|
G:\Heloworld\matrytsja\matrytsja.cpp|9|error: anachronistic old-style base class initializer [-fpermissive]|
G:\Heloworld\matrytsja\matrytsja.cpp|9|error: unnamed initializer for 'matrytsja', which has no base classes|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 9 second(s)) ===|


Завжди здається я так писав, і от на тобі, це ж таке треба....  Я навить английською одразу все зрозумів.   А як тоді треба??

2

Re: Яким повинен бути конструктор класу?

Дмитро-Чебурашка написав:

Завжди здається я так писав, і от на тобі, це ж таке треба....  Я навить английською одразу все зрозумів.   А як тоді треба??

Та ви шо?
А може таки так: matrytsja(int _x=0, int _y=0) : x(_x),  y(_y)?

3

Re: Яким повинен бути конструктор класу?

Це перше, друге імена з підкресленням спереді зарезервовані стандартною бібліотекою, тому не раджу писати так: _x, _y ... краще тоді вже x_, y_
Третє, у вас в коді UB в цьому рядку

m[i]=new int [y];
Подякували: Дмитро-Чебурашка1

Re: Яким повинен бути конструктор класу?

Тупо сидів роздивлявсь і раптом зрозумів.

matrytsja(int _x=0, int _y=0) : x(_x),  y(_y)

Повідомлення компілятора таке, що одразу що завгодно подумаєш, тільки не те що воно є.

5

Re: Яким повинен бути конструктор класу?

Дмитро-Чебурашка написав:

Тупо сидів роздивлявсь і раптом зрозумів.

matrytsja(int _x=0, int _y=0) : x(_x),  y(_y)

Повідомлення компілятора таке, що одразу що завгодно подумаєш, тільки не те що воно є.

Тобто вас зі всього написаного лише конструктор бентежить?

6

Re: Яким повинен бути конструктор класу?

adziri написав:

Третє, у вас в коді UB в цьому рядку

m[i]=new int [y];

Нагадайте в чому тут проблема?

7 Востаннє редагувалося wander (14.08.2019 11:25:44)

Re: Яким повинен бути конструктор класу?

sensei написав:
adziri написав:

Третє, у вас в коді UB в цьому рядку

m[i]=new int [y];

Нагадайте в чому тут проблема?

В загалом потенційно UB не лише в цьому рядку, а взагалі всюди коли буде спроба доступу до int **m;
Так чому ж тут UB? Ну, погляньмо на параметри конструктора: matrytsja(int _x=0, int _y=0)
_x, _y - в даному випадку по замовчуванню рівні 0, вони ж надалі ініціалізують відповідні поля класу, теж 0.
Після чого в тілі конструктора одразу відбувається виділення пам'яті m=new int*[x] на 0 елементів.
Стандарт С++ дозволяє таку поведінку і дозволяє виділяти динамічно масив на 0 елементів (хоча це і не зовсім масив вже), проте будь-який доступ або спроба розіменувати такий вказівник - UB.

http://eel.is/c++draft/expr.new#9 написав:

When the value of the expression is zero, the allocation function is called to allocate an array with no elements.

Звідси

If the size of the space requested is zero, the behavior is implementation defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

Звісно ТС в даному випадку явно задавав х, у, але це ні про що не говорить, варто залишити все як є і обов'язково вистрілимо собі в ногу.

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