Форум программистов, компьютерный форум CyberForum.ru

Поле класса - динамический массив - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
OdessaNA
 Аватар для OdessaNA
19 / 19 / 0
Регистрация: 10.01.2011
Сообщений: 240
30.12.2012, 23:37     Поле класса - динамический массив #1
Здравствуйте, друзья.
Проверьте, пожалуйста, всё ли правильно написано (отсутствие сообщений об ошибках не исключает их присутствия).
Цель - создать класс с указателем типа int. Этот поле использовать как динамический массив.
Вот код:
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
#include <iostream>
#include <conio.h>
using namespace std;
 
const int SIZE = 3;
 
class DinArr
{
    int *array;
    int length;
public:
    DinArr() { array = new int [SIZE]; length = 0; }
    DinArr(const DinArr&);
    ~DinArr () { delete [] array; }
    void Verific( int );
    void Add( int );
    void Show();
 
};
DinArr :: DinArr(const DinArr& obj)
{
    array = obj.array;
    length = obj.length;
}
 
void DinArr :: Verific( int x )
{
    if( x >= SIZE)
    {
         int *temp = new int [x + 1];
         for(int i = 0; i < x; ++i)
         {
             temp[i] = array[i];
         }
         array = temp;
    }
}
 
void DinArr :: Add( int x )
{
    Verific( length );
    
    array[length++] = x;
}
 
void DinArr :: Show()
{
    for(int i = 0; i < length; ++i)
    {
        cout << array[i] << ' ';
    }
    cout << endl;
}
 
void main()
{
    DinArr obj;
 
    int z=0;
 
    while(z < 5)
    {
        obj.Add(7);
        z++;
    }
 
    obj.Show();
 
    _getch();
}
Интересует вопрос - очищается ли вся выделенная память?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,620
Записей в блоге: 17
31.12.2012, 01:13     Поле класса - динамический массив #2
C++
1
2
3
4
5
DinArr :: DinArr(const DinArr& obj)
{
    array = obj.array;
    length = obj.length;
}
Это не правильно, и еще нехватает перегрузки оператора присвоения
Uvi
1 / 1 / 0
Регистрация: 22.05.2012
Сообщений: 18
31.12.2012, 04:22     Поле класса - динамический массив #3
C++
1
2
3
4
5
6
7
8
9
DinArr :: DinArr(const DinArr& obj)
{
    this->arr=new int[obj.length];
    for(int i=0;i<obj.length;i++)
    {
        arr[i]=obj.arr[i];
    }
    this->length=obj.length;
}
во первых нужно выделить память для твоего поинтера, а потом делать глубокое копирование .
То что ты сделал, если выделить память, тоже будет работать. Я тоже студент, далеко не специалист. Нас учили, что правильнее переписывать глубоко все переменные. С интеджерами это работает, но есле у тебя кроме них еще куча всего будет внутри, то не факт.
кроме этого вместо array нужно поставить другое название, например arr (как я поставил) в копи констракторе,
array - это уже готовый массив в библиотеке.
UserAK
70 / 70 / 4
Регистрация: 25.12.2012
Сообщений: 189
Записей в блоге: 2
31.12.2012, 05:57     Поле класса - динамический массив #4
если есть new, то должен быть и delete
например
C++
1
int *temp = new int [x + 1];
...
надо бы сначала
C++
1
delete[] array;
а уж потом
C++
1
array = temp;
Добавлено через 8 минут
чтоб было веселее можно вместо void DinArr::Show() перегрузить оператор <<

Добавлено через 6 минут
Цитата Сообщение от Uvi Посмотреть сообщение
array - это уже готовый массив в библиотеке.
впринципе это не особо страшно, просто придётся указывать пространство имён, но конечно для удобства лучше избегать таких ситуаций.
многие используют в именах переменных членов класса приставку m_
получится m_array

Добавлено через 13 минут
Цитата Сообщение от Uvi Посмотреть сообщение
правильнее переписывать глубоко все переменные
почти у всех классов имеются закрытые члены, и поэтому в особых случаях надо использовать специальные функции вроде assign.
а структуры и так прекрасно копируются. вообще за правильное копирование отвечает разработчик класса.

Добавлено через 9 минут
Цитата Сообщение от OdessaNA Посмотреть сообщение
DinArr() { array = new int [SIZE]; length = 0; }
получается размер массива и length разные
OdessaNA
 Аватар для OdessaNA
19 / 19 / 0
Регистрация: 10.01.2011
Сообщений: 240
31.12.2012, 17:41  [ТС]     Поле класса - динамический массив #5
Цитата Сообщение от Avazart Посмотреть сообщение
C++
1
2
3
4
5
DinArr :: DinArr(const DinArr& obj)
{
    array = obj.array;
    length = obj.length;
}
Это не правильно, и еще нехватает перегрузки оператора присвоения
Ёлку установил, можно и исправить:

C++
1
2
3
4
5
6
7
8
9
10
DinArr :: DinArr(const DinArr& obj)
{
    length = obj.length;
 
    array = new int [length + 1];
    for (int i = 0; i < length; i++)
    {
        array[i] = obj.array[i];
    }
}
... перегрузка будет "между" салатами и отбивными.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,620
Записей в блоге: 17
31.12.2012, 17:46     Поле класса - динамический массив #6
А зачем length + 1 ?
OdessaNA
 Аватар для OdessaNA
19 / 19 / 0
Регистрация: 10.01.2011
Сообщений: 240
31.12.2012, 20:43  [ТС]     Поле класса - динамический массив #7
Цитата Сообщение от Avazart Посмотреть сообщение
А зачем length + 1 ?
Т.к. в моём классе length - индекс элементов. Соответственно размер массива length+1 .
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,620
Записей в блоге: 17
31.12.2012, 20:46     Поле класса - динамический массив #8
Т.е. ? length обычно обозначают размер массива ?
Зачем выделять на один элемент больше ?
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
31.12.2012, 21:34     Поле класса - динамический массив #9
OdessaNA, на каждый new должен приходиться delete. (new[] / delete[]). Вот и считайте.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,620
Записей в блоге: 17
31.12.2012, 21:36     Поле класса - динамический массив #10
C++
1
2
3
4
5
6
7
8
9
10
11
12
void DinArr :: Verific( int x )
{
    if( x >= SIZE)
    {
         int *temp = new int [x + 1];
         for(int i = 0; i < x; ++i)
         {
             temp[i] = array[i];
         }
         array = temp;
    }
}
Эту ф-цию надо переписать с учетом того что сказал go
OdessaNA
 Аватар для OdessaNA
19 / 19 / 0
Регистрация: 10.01.2011
Сообщений: 240
01.01.2013, 18:47  [ТС]     Поле класса - динамический массив #11


Добавлено через 9 минут
Спасибо, друзья, за помощь!
Учел Ваши подсказки и замечания, и переписал код:
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
#include <iostream>
#include <conio.h>
using namespace std;
 
class DinArr
{
    int *array;
    int size;
public:
    DinArr();
    ~DinArr() { delete [] array; }
    DinArr(const DinArr&); //
    DinArr operator = (const DinArr&); //
    DinArr& operator ++ (); //
    DinArr& operator -- (); //
    void Add( int );
    void Show();
};
 
DinArr :: DinArr()
{
    size = 0;
    array = new int [size + 1];
}
 
DinArr :: DinArr(const DinArr& obj)
{
    size = obj.size;
 
    array = new int [size];
    for(int i = 0; i < size; ++i)
        array[i] = obj.array[i];
}
 
DinArr DinArr :: operator = (const DinArr& obj)
{
    size = obj.size;
 
    delete [] array;
 
    array = new int [size];
    for(int i = 0; i < size; ++i)
        array[i] = obj.array[i];
 
    return *this;
}
 
DinArr& DinArr :: operator ++ ()
{
 
    int *temp = new int[size + 1];
    for(int i = 0; i < size; ++i)
        temp[i] = array[i];
 
    delete [] array;
    array = temp;
 
    ++size;
    array[size-1] = 0;
 
    return *this;
}
 
DinArr& DinArr :: operator -- ()
{
    --size;
 
    int *temp = new int [size];
    for(int i = 0; i < size; ++i)
        temp[i] = array[i];
 
    delete [] array;
    array = temp;
 
    return *this;
}
 
void DinArr :: Add( int x )
{
        int *temp = new int [size + 1];
        for(int i = 0; i < size; ++i)
            temp[i] = array[i];
        
        delete [] array;
        array = temp;
 
        array[size] = x;
        ++size;
}
 
void DinArr :: Show()
{
    for(int i = 0; i < size; ++i)
        cout << array[i] << ' ';
    cout << endl;
}
 
void main()
{
    DinArr obj, obj2;
    
    int i = 0;
 
    while(i < 10)
        obj.Add(++i);
 
    obj.Show();
 
    obj2 = obj;
    ++obj2;
    --obj2;
 
    obj2.Show();
    
    _getch();
}
У меня остались некоторые сомнения по конструктору копирования. Подскажите, пожалуйста, он правильно реализован, или в нём есть ошибка?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
01.01.2013, 19:02     Поле класса - динамический массив #12
Всё окей. (Чтоб всё точно было окей, стоит перенести инициализацию размеров после оператора new. Если new сломается, то у вас будет хотя бы пустой массив, а не чёрти что.)
MrCold
851 / 749 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
01.01.2013, 19:58     Поле класса - динамический массив #13
Цитата Сообщение от OdessaNA Посмотреть сообщение
сомнения по конструктору копирования
delete пропустили , без него будет утечка памяти
C++
1
2
3
4
5
6
7
8
9
DinArr :: DinArr(const DinArr& obj)
{   
       delete [] array;
 
    array = new int [obj.size];
      size = obj.size;
    for(int i = 0; i < size; ++i)
        array[i] = obj.array[i];
}
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
01.01.2013, 20:41     Поле класса - динамический массив #14
Зачем? Это конструктор, 1) он вызывается один раз, 2) значение array не определено. А в operator=() delete[] есть.
MrCold
851 / 749 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
01.01.2013, 20:45     Поле класса - динамический массив #15
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Это конструктор, 1) он вызывается один раз
Точно
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
01.01.2013, 21:13     Поле класса - динамический массив #16
Цитата Сообщение от OdessaNA Посмотреть сообщение
void Show();
Должна быть const.
Цитата Сообщение от OdessaNA Посмотреть сообщение
DinArr :: DinArr()
{
* * size = 0;
* * array = new int [size + 1];
}
Непонятен этот size + 1. Почему не NULL?
Цитата Сообщение от OdessaNA Посмотреть сообщение
DinArr DinArr :: operator = (const DinArr& obj)
{
* * size = obj.size;
delete [] array;
array = new int [size];
* * for(int i = 0; i < size; ++i)
* * * * array[i] = obj.array[i];
return *this;
}
Желательно возвращать ссылку(по аналогии со встроенными типами). И где проверка на присваивание объекту его собственной копии?
P.S. Касательно
C++
1
2
delete [] array;
array = new int [size];
При возникновении исключения в случае ошибки выделения памяти, после выполнения delete [] array, array так и останется "неинициализированным" указателем. При этом, во время обработки исключения декструктор данного(уже сконструированного) объекта всеравно будет вызван. Для того чтобы избежать повторного вызова delete [] array в деструкторе, после освобождения памяти данный указатель следует обнулить.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.01.2013, 21:41     Поле класса - динамический массив
Еще ссылки по теме:

C++ Реализовать шаблон класса vector, реализующий динамический массив
C++ Массив внутри класса (игровое поле)
Динамический массив класса C++

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

Или воспользуйтесь поиском по форуму:
OdessaNA
 Аватар для OdessaNA
19 / 19 / 0
Регистрация: 10.01.2011
Сообщений: 240
01.01.2013, 21:41  [ТС]     Поле класса - динамический массив #17
rangerx, ~OhMyGodSoLong~, спасибо за поправки!

Добавлено через 15 минут
Внес изменения с учетом Ваших замечаний. Теперь "читабельнее".
Ещё раз спасибо!
Yandex
Объявления
01.01.2013, 21:41     Поле класса - динамический массив
Ответ Создать тему
Опции темы

Текущее время: 23:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru