Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 01.05.2015
Сообщений: 4

Конструктор по умолчанию вызывается после конструктора инициализации

15.05.2015, 19:22. Показов 1644. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Во время выполнения программы потомок не может использовать матрицу, инициализированную в предке. Я создала конструктор с параметрами, в котором эта инициализация и происходит, но Visual сказал мне еще создать конструктор по умолчанию. Как раз этот конструктор скорее всего и вызывает проблему. Он почему-то всегда вызывается после конструктора инициализации и в нем указатель на матрицу возможно теряет своё значение. Я не знаю как его убрать. Скрин с выдаваемой ошибкой, значениями и строкой, на которой программа останавливается во вложении.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*Описать тип-объект MATRIX (матрица произвольной размерности M*N) и его методы: ввод матрицы; вывод матрицы; определение минимального элемента среди отрицательных элементов матрицы.
Описать тип и методы его потомка MATR (методы: определение наибольшего общего делителя элементов матрицы; определение максимального среди неповторяющихся элементов матрицы  ).*/
#include <iostream>
#include <clocale>//для setlocale(LC_ALL,"");
using namespace std;
 
class MATRIX
{
protected:
    int *mx;//Указатель на матрицу
    int negmin;//переменная для значения минимального отрицательного числа
    int n, m;//количество строк и столбцов матрицы
public:
    MATRIX();
    MATRIX(int o,int q);//параметры количества строк и столбцов матрицы
    ~MATRIX();
    virtual void show(void);//Показывает массив
    int search_negmin(void);//возвращает минимум среди отрицательных эл-тов матрицы
};
 
MATRIX::MATRIX()
{
    cout << "\nКонструктор MATRIX по умолчанию. Visual попросил его создать зачем-то.\n";
}
 
MATRIX::MATRIX(int o, int q)
{
    cout << "\nКонструктор MATRIX\n";
    negmin = 0;
    n = o;
    m = q;
    mx = new int[n*m];//выделение памяти под матрицу динамически
    if (!mx)
    {
        cout << "\nНедостаточно памяти для матрицы\a";
    }
    for (int i = 0; i < n; i++)//ввод матрицы
        for (int j = 0; j < m; j++)
        {
        cout << "\nВведите элемент матрицы под номером [" << i + 1 << "][" << j + 1 << "]=";
        cin >> *(mx+i*m+j);
        }
    cout << "\nМатрица введена"<<endl;
}
 
MATRIX::~MATRIX()
{
    delete[] mx;
    cout << "\nМатрица разрушена"<<endl;
}
 
void MATRIX::show(void)
{
    cout << "\nВы ввели матрицу:\n";
    for (int i = 0; i < n; i++)//cout << endl, i++
    {
        for (int j = 0; j < m; j++)
            cout << *(mx + i*m + j) << "\t";//вывод элементов матрицы
        cout << endl;//переход на новую строку после вывода всех элементов строки
    }
}
 
int MATRIX::search_negmin(void)
{
    negmin = mx[0];//присвоение первого эл-та матрицы negmin 
    for (int i = 0; i < n*m; i++)//цикл по всем элементам с поиском минимального значения и присвоения его negmin
    {
        if (negmin > mx[i]) negmin = mx[i];
    }
    if (negmin >= 0) cout << "\nВ матрице отсутствуют отрицательные элементы. Минимальный элемент = " << negmin << endl;
    else cout << "\nМинимальный элемент среди отрицательных = " << negmin << endl;
    return negmin;
}
 
class MATR:public MATRIX
{
public:
    MATR();
    ~MATR();
    int nod(void);//ищет и возвращает НОД эдементов матрицы
    int nonrepmax(void);//ищет и возвращает max среди неповторяющихся эл-тов матрицы
    void show(void);
private:
    int valnod, nrmax;
};
 
MATR::MATR()
{
    cout << "\nКонструктор MATR"<<endl;
    valnod = 0;
    nrmax = 0;
}
 
MATR::~MATR()
{
    cout << "\nДеструктор MATR по умолчанию" << endl;
}
 
int MATR::nod(void)
{
    //Нахождение НОД по алгоритму Евклида делением и при помощи свойств НОД
    cout << "\nНахождение наибольшего общего делителя элементов матрицы";
    int counter = 0;//счетчик количества итераций цикла for
    int a = static_cast<unsigned int>(mx[0]);
    int b;
    for (int i = 0; i < (n*m-1); i++)
    {
        b = static_cast<unsigned int> (mx[i + 1]);
        while (a != 0 && b != 0)
        {
            if (a > b) a %= b;
            else b %= a;
        }
        a += b;
        counter++;
        }
    if (counter = 1) valnod = a;//это условие нужно для того, если вдруг матрица будет состоять всего из двух элементов
    else valnod = a + b;
    cout << "\nНОД всех элементов матрицы = " << valnod << endl;
    return valnod;
}
 
int MATR::nonrepmax(void)
{
    cout << "\nИщем максимальный среди неповторяющихся элементов матрицы"<<endl;
    //сортируем матрицу по убыванию
    for (int i = 0; i < n*m; i++)
    {
        if (mx[i]>mx[i+1])
        {
            int inter = 0;
            inter = mx[i];
            mx[i] = mx[i + 1];
            mx[i + 1] = inter;
        }
    }
    //ищем в отсортированной матрице максимум среди неповторяющихся элементов
    int counter = 1;//счетчик количества пар повторяющихся элементов
    for (int i = 0; i < n*m; i++)
    {
        if (mx[i]=mx[i + 1])
        {
            i += 2;
            counter++;
        }
        else nrmax = mx[i];
    }
    if (counter = n*m / 2)//if(!*nrmax)
    {
        cout << "\nМаксимума среди неповторяющихся элементов не существует в данной матрице\a" << endl;
        return -1;
    }
    return nrmax;
}
 
void MATR::show(void)
{
    cout << "\nМатрица после сортировки:\n";
    for (int i = 0; i < n; i++)//cout << endl, i++
    {
        for (int j = 0; j < m; j++)
            cout << *(mx + i*m + j) << "\t";//вывод элементов матрицы
        cout << endl;//переход на новую строку после вывода всех элементов строки
    }
}
 
void main(void)
{
    setlocale(LC_ALL, "");
    int o, q;
    cout << "\nВведите количество строк в матрице: ";
    cin >> o;
    cout << "\nВведите количество столбцов в матрице: ";
    cin >> q;
    MATRIX objf, obj1(o, q), *p;
    p = &obj1;
    p->show();
    obj1.search_negmin();
    MATR obj2;
    obj2.nod();
    obj2.nonrepmax();
    p = &obj2;
    p->show();
}
Миниатюры
Конструктор по умолчанию вызывается после конструктора инициализации  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.05.2015, 19:22
Ответы с готовыми решениями:

Можно ли использовать конструктор по умолчанию и конструктор инициализации одновременно?
Можно ли использовать конструктор по умолчанию и конструктор инициализации одновременно?

Определить конструктор для инициализации полей по умолчанию
У меня такое задание по лабу, кстати она самая сложная и последняя: дана структура: struct Student { char *LastName; ...

Почему в списке инициализации конструктора дочернего класса нельзя вызывать конструктор родительского через его пространство имён?
Есть класс D и от него порождён класс Wd Тут вот например всё работает корректно (использую обращение ч/з пространство имён класса...

8
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.05.2015, 01:17
Цитата Сообщение от Pintara Посмотреть сообщение
Я создала конструктор с параметрами
А вызывать его кто будет, Страустрап? Напишите MATR::MATR():MATRIX(1,1) и никто с вас конструкторов по умолчанию требовать не будет. Ну или конструктор по умолчанию сделайте редиректом на конструктор с аргументами (MATRIX():MATRIX(1,1){}).
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.05.2015, 17:34
Цитата Сообщение от Pintara Посмотреть сообщение
но Visual сказал мне еще создать конструктор по умолчанию
В строке 175 есть объект objf, который требует конструктора по умолчанию (т.к. явно никакой другой конструктор не указан)

Цитата Сообщение от Pintara Посмотреть сообщение
Он почему-то всегда вызывается после конструктора инициализации
Конструктор вызывается только один. Их может быть много (с разными параметрами), но при создании какждого объекта вызовется только один из них (конструкторов)

C++
MATRIX objf, obj1(o, q)
После objf ничего в скобках не написано, значит после создания objf будет вызван конструктор без параметров (то бишь по умолчанию MATR::MATR()). После obj1 в скобках написано две величины типа int, значит будет вызван конструктор MATR::MATR(int,int)
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.05.2015, 18:17
Цитата Сообщение от Evg Посмотреть сообщение
Конструктор вызывается только один.
Нет, здесь как раз будет два - конструктор предка и конструктор потомка. А в C++11 и того хлеще - несколько конструкторов одного объекта, могут вызывать друг друга по цепочке.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.05.2015, 18:37
Цитата Сообщение от Renji Посмотреть сообщение
Нет, здесь как раз будет два - конструктор предка и конструктор потомка
Невнимательно посмотрел, не заметил, что там два разных класса MATR и MATRIX
0
0 / 0 / 0
Регистрация: 01.05.2015
Сообщений: 4
16.05.2015, 18:59  [ТС]
Цитата Сообщение от Renji Посмотреть сообщение
Напишите MATR::MATR():MATRIX(1,1) и никто с вас конструкторов по умолчанию требовать не будет. Ну или конструктор по умолчанию сделайте редиректом на конструктор с аргументами (MATRIX():MATRIX(1,1){}).
Воспользовалась этим предложением.
Цитата Сообщение от Evg Посмотреть сообщение
В строке 175 есть объект objf, который требует конструктора по умолчанию (т.к. явно никакой другой конструктор не указан)
А также убрала этот ненужный объект.
Программа теперь идёт до конца, но все равно вызывается слишком много конструкторов и деструкторов.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*Описать тип-объект MATRIX (матрица произвольной размерности M*N) и его методы: ввод матрицы; вывод матрицы; определение минимального элемента среди отрицательных элементов матрицы.
Описать тип и методы его потомка MATR (методы: определение наибольшего общего делителя элементов матрицы; определение максимального среди неповторяющихся элементов матрицы  ).*/
#include <iostream>
#include <clocale>//для setlocale(LC_ALL,"");
#include <cstdlib>
using namespace std;
 
class MATRIX
{
protected:
    int *mx;//Указатель на матрицу
    int negmin;//переменная для значения минимального отрицательного числа
    int n, m;//количество строк и столбцов матрицы
public:
    int o, q;
    MATRIX();
    MATRIX(int o, int q);//параметры количества строк и столбцов матрицы
    ~MATRIX();
    virtual void show(void);//Показывает массив
    int search_negmin(void);//возвращает минимум среди отрицательных эл-тов матрицы
};
 
 
 
MATRIX::MATRIX(int o, int q)
{
    cout << "\nКонструктор MATRIX\n";
    negmin = 0;
    n = o;
    m = q;
    mx = new int[n*m];//выделение памяти под матрицу динамически
    if (!mx)
    {
        cout << "\nНедостаточно памяти для матрицы\a";
    }
    for (int i = 0; i < n; i++)//ввод матрицы
        for (int j = 0; j < m; j++)
        {
        cout << "\nВведите элемент матрицы под номером [" << i + 1 << "][" << j + 1 << "]=";
        cin >> *(mx + i*m + j);
        }
    cout << "\nМатрица введена" << endl;
}
 
MATRIX::MATRIX() :MATRIX(o, q)
{
    cout << "\nКонструктор MATRIX по умолчанию. Visual попросил его создать зачем-то.\n";
}
 
MATRIX::~MATRIX()
{
    delete[] mx;
    cout << "\nМатрица разрушена" << endl;
    system("pause");
}
 
void MATRIX::show(void)
{
    cout << "\nВы ввели матрицу:\n";
    for (int i = 0; i < n; i++)//cout << endl, i++
    {
        for (int j = 0; j < m; j++)
            cout << *(mx + i*m + j) << "\t";//вывод элементов матрицы
        cout << endl;//переход на новую строку после вывода всех элементов строки
        system("pause");
    }
}
 
int MATRIX::search_negmin(void)
{
    negmin = mx[0];//присвоение первого эл-та матрицы negmin 
    for (int i = 0; i < n*m; i++)//цикл по всем элементам с поиском минимального значения и присвоения его negmin
    {
        if (negmin > mx[i]) negmin = mx[i];
    }
    if (negmin >= 0) cout << "\nВ матрице отсутствуют отрицательные элементы. Минимальный элемент = " << negmin << endl;
    else cout << "\nМинимальный элемент среди отрицательных = " << negmin << endl;
    system("pause");
    return negmin;
}
 
class MATR :public MATRIX
{
public:
    MATR();
    ~MATR();
    int nod(void);//ищет и возвращает НОД эдементов матрицы
    int nonrepmax(void);//ищет и возвращает max среди неповторяющихся эл-тов матрицы
    void show(void);
private:
    int valnod, nrmax;
};
 
//MATR::MATR():MATRIX(o,q)
MATR::MATR() :MATRIX(o, q)
{
    cout << "\nКонструктор MATR" << endl;
    valnod = 0;
    nrmax = 0;
}
 
MATR::~MATR()
{
    cout << "\nДеструктор MATR по умолчанию" << endl;
    system("pause");
}
 
int MATR::nod(void)
{
    //Нахождение НОД по алгоритму Евклида делением и при помощи свойств НОД
    cout << "\nНахождение наибольшего общего делителя элементов матрицы";
    int counter = 0;//счетчик количества итераций цикла for
    int a = static_cast<unsigned int>(mx[0]);
    int b;
    for (int i = 0; i < (n*m - 1); i++)
    {
        b = static_cast<unsigned int> (mx[i + 1]);
        while (a != 0 && b != 0)
        {
            if (a > b) a %= b;
            else b %= a;
        }
        a += b;
        counter++;
    }
    if (counter = 1) valnod = a;//это условие нужно для того, если вдруг матрица будет состоять всего из двух элементов
    else valnod = a + b;
    cout << "\nНОД всех элементов матрицы = " << valnod << endl;
    system("pause");
    return valnod;
}
 
int MATR::nonrepmax(void)
{
    cout << "\nИщем максимальный среди неповторяющихся элементов матрицы" << endl;
    //сортируем матрицу по убыванию
    for (int i = 0; i < n*m; i++)
    {
        if (mx[i]>mx[i + 1])
        {
            int inter = 0;
            inter = mx[i];
            mx[i] = mx[i + 1];
            mx[i + 1] = inter;
        }
    }
    //ищем в отсортированной матрице максимум среди неповторяющихся элементов
    int counter = 1;//счетчик количества пар повторяющихся элементов
    for (int i = 0; i < n*m; i++)
    {
        if (mx[i] = mx[i + 1])
        {
            i += 2;
            counter++;
        }
        else nrmax = mx[i];
    }
    if (counter = n*m / 2)//if(!*nrmax)
    {
        cout << "\nМаксимума среди неповторяющихся элементов не существует в данной матрице\a" << endl;
        return -1;
    }
    else cout << "\nМаксимум среди неповторяющихся эл-тов марицы = " << nrmax << endl;
    system("pause");
    return nrmax;
}
 
void MATR::show(void)
{
    cout << "\nМатрица после сортировки:\n";
    for (int i = 0; i < n; i++)//cout << endl, i++
    {
        for (int j = 0; j < m; j++)
            cout << *(mx + i*m + j) << "\t";//вывод элементов матрицы
        cout << endl;//переход на новую строку после вывода всех элементов строки
        system("pause");
    }
}
 
void main(void)
{
    setlocale(LC_ALL, "");
    int o, q;
    cout << "\nВведите количество строк в матрице: ";
    cin >> o;
    cout << "\nВведите количество столбцов в матрице: ";
    cin >> q;
    MATR obj2;
    MATRIX obj1(o, q), *p;
    p = &obj1;
    p->show();
    obj1.search_negmin();
    //MATR obj2;
    obj2.nod();
    obj2.nonrepmax();
    p = &obj2;
    p->show();
    system("pause");
}
Миниатюры
Конструктор по умолчанию вызывается после конструктора инициализации  
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.05.2015, 19:22
Цитата Сообщение от Pintara Посмотреть сообщение
Программа теперь идёт до конца, но все равно вызывается слишком много конструкторов и деструкторов.
Нет, с конструкторами все правильно - два на объект MATR, один на объект MATRIX. Дело в том что конструктор потомка, это надстройка над конструктором предка. И всегда вызывается после этого самого конструктора предка (а также конструкторов всех полей вашего класса). Вы можете задать какой конструктор предка будет вызван, можете сделать конструктор предка пустым, но избавиться от его вызова не сможете. Так и задумано.

Тоже самое с деструктором - сначала отработает деструктор потомка, а потом в обязательном порядке деструктор предка. Опять же, так и задумано. Предок должен сам подчищать за собой ресурсы, а не перекладывать эту задачу на потомка.
Цитата Сообщение от Pintara Посмотреть сообщение
MATRIX::MATRIX() :MATRIX(o, q)
А вот это неправильно, потому как в o и q у вас будет мусор. Нужно проставить вместо них конкретные цифры.
0
0 / 0 / 0
Регистрация: 01.05.2015
Сообщений: 4
16.05.2015, 19:39  [ТС]
Цитата Сообщение от Renji Посмотреть сообщение
Сообщение от Pintara
MATRIX::MATRIX() :MATRIX(o, q)
А вот это неправильно, потому как в o и q у вас будет мусор. Нужно проставить вместо них конкретные цифры.
Но у меня значения этим параметрам присваиваются в процессе выполнения программы. Какие же числа тогда записать?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.05.2015, 20:23
Цитата Сообщение от Pintara Посмотреть сообщение
Но у меня значения этим параметрам присваиваются в процессе выполнения программы.
Значит, не создавайте конструктора по умолчанию, а в main напишите MATR obj2(o,q);. Конструктор по умолчанию, предполагает что и содержимое объекта будет "по умолчанию". Если это "по умолчанию" не придумывается, то и конструктор не нужен.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.05.2015, 20:23
Помогаю со студенческими работами здесь

Конструктор Шредингера "нет подходящего конструктора по умолчанию", хотя он есть
собственно, код. на 156-й строке ( cont(circi);) ругается на отсутствие конструктора в классе. но он там есть! я его видел! а если...

Visual жалуется на конструктор "Error C2512: нет подходящего конструктора по умолчанию"
Привет, мне Visual C++ выдал такие ошибки делаю все как в уроке, пытаюсь описать класс в заголовочном файле, вот код с...

При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
Вот такой кодclass A { public: A(){} virtual ~A(){} }; class C { public:

this(Всегда ли вызывается конструктор при не явной передачи объекта в конструктор)
class Test { int i; public: void test(int i) { this -&gt; i = i; } }; Конструктор Test::Test всегда вызывается...

Конструктор инициализации, конструктор копирования, деструктор
Я сделал почти задание по перегрузке операторов. Осталось одно, тоесть три: конструктор инициализации, конструктор копирования, деструктор....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru