Форум программистов, компьютерный форум, киберфорум
Тамика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Ещё чуть-чуть вектора.

Запись от Тамика размещена 01.07.2014 в 13:35
Показов 3857 Комментарии 6
Метки c++

Всем бобрового утра!
Кто читает это уже не утром - бобрового дня или вечера.
Так вот.
Скучным рабочим утром решила стряхнуть пыль с проекта под названием int_array. И малость его доработать.
Были внесены следующие изменения:
1) Убрана недоработка, на которую указал SatanaXIII.
2) Использованы ценные советы Jupiter.
3) Усовершенствован конструктор - теперь он не просто принимает размер будущего вектора, а может еще и принимать желаемое значение!
4) Изменила возвращаемые значения у getSize() и getCapacity - раз уж они у нас должны быть более нуля, то сняла их с int и посадила на size_t.

Изменения не существенны, однако это ещё один шаг к улучшению вектора.
В следующем сезоне "Таня и Вектор" - обобщение класса и превращение его в шаблон.

И снова внимательно прислушиваюсь к комментариям старших. Спасибо за внимание!

Итак.
Сосбна, хедерок.
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
#pragma once
#include <stdexcept>
#include <algorithm> 
 
class IntVector
{
    int *mas;
    size_t size, capacity;
public:
    
    IntVector();
 
    ~IntVector();
 
    IntVector(const IntVector& in);
 
    explicit IntVector(const size_t aSize, const int val = 0);
 
    size_t getSize() const;
 
    size_t getCapacity() const;
 
    void resize(size_t n);
 
    void reserve(size_t n);
 
    void pushBack(int val);
 
    void popBack();
 
    int& operator[] (size_t n);
 
    const int& operator[] (size_t n) const;
 
    int& at(size_t n);
 
    IntVector& operator= (const IntVector& in);
 
    void clear();
 
    void erase(size_t index);
 
    bool empty() const;
 
    int front() const;
 
    int back() const;
 
    int& front();
 
    int& back();
 
    void swap (IntVector &in) throw ();
};
А теперь сама начинка.
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
#include "int_array.h" 
 
 
IntVector::~IntVector()
{
    delete [] mas;
}
 
IntVector::IntVector() : mas(0), size(0), capacity(0)
{
}
 
IntVector::IntVector(const IntVector& in)
{
    size = in.size;
    capacity = in.capacity;
    mas = new int[capacity];
    for (int i = 0; i < size; ++i)
        mas[i] = in.mas[i];
}
 
IntVector::IntVector(const size_t aSize, const int val)
{
    mas = new int[aSize];
    size = aSize;
    capacity = aSize;
    for (int i = 0; i < size; ++i)
        mas[i] = val;
}
 
size_t IntVector::getSize() const
{
    return size;
}
 
size_t IntVector::getCapacity() const
{
    return capacity;
}
 
void IntVector::reserve(size_t n)
{
    if (n > capacity)
    {
        int *temp = new int[n];
        capacity = n;
        for (int i = 0; i < size; ++i)
            temp[i] = mas[i];
        delete []mas;
        mas = temp;
    }
}
 
void IntVector::resize(size_t n)
{
    if (size > n)
    {
        size = n;
        return;
    }
    if (size < n)
    {
        reserve(n);
        for (int i = size; i < n; ++i)
            mas[i] = 0;
    }
}
 
void IntVector::pushBack(int val)
{
    if (size >= capacity)
    {
        size_t new_size = size + 1;
        reserve(new_size + new_size / 2);
    }
    mas[size++] = val;
}
 
void IntVector::popBack()
{
    if (size >= 1)
        --size;
}
 
int& IntVector::operator[] (size_t n)
{
    return mas[n];
}
 
const int& IntVector::operator[] (size_t n) const
{
    return mas[n];
}
 
int& IntVector::at(size_t n)
{
    if (n >= size)
        throw std::out_of_range("Index out of range!");
    return mas[n];
}
 
IntVector& IntVector::operator= (const IntVector& in)
{
    IntVector temp(in);
    temp.swap(*this);
    return *this;
}
 
void IntVector::swap(IntVector& in) throw()
{
    std::swap(mas, in.mas);
    std::swap(size, in.size);
    std::swap(capacity, in.capacity);
}
 
void IntVector::clear()
{
    size = 0;
}
 
void IntVector::erase(size_t index)
{
    if (index >= size) 
        throw std::out_of_range("Index out of range!");
    --size;
    for (int i = index; i < size; ++i)
        mas[i] = mas[i + 1];
}
 
bool IntVector::empty() const
{
    return size == 0;
}
 
int IntVector::front() const
{
    return mas[0];
}
 
int IntVector::back() const
{
    return mas[size-1];
}
 
int& IntVector::front()
{
    return mas[0];
}
 
int& IntVector::back()
{
    return mas[size-1];
}
Метки c++
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 6
Комментарии
  1. Старый комментарий
    Аватар для SatanaXIII
    1) Я ж вот здесь вот как-то говорил уже, что раз есть throw() в описании, то должен быть и в реализации в реализации. Это ж две разные функции получаются:
    C++
    1
    2
    
    void IntVector::swap(IntVector& in)
    void IntVector::swap(IntVector& in) throw()
    Представленный код тупо не запустится.

    2) Вот это вот замечание HighPredator тоже прошло без внимания. Зачем два механизма? Дефайнов вполне достаточно.

    3) Многие старые компиляторы не подключают по умолчанию заголовки для работы с size_t. Можно перед классом это проверить. Хотя заместо этого так же можно и подключаемые модули перенести в хедер. Они-то обладают знаниями о size_t.
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    //#include <stdexcept>
    //#include <algorithm>
     
    #ifndef __STDDEF_H
    #include <stddef.h>
    #endif
     
    class IntVector
    {
        int *mas;
        size_t size, capacity;
    public:
    4) Зачем опять указывать область видимости внутри себя же:
    C++
    11
    
    /*IntVector::*/IntVector();
    5) Метод resize просто выбрасывает кусок памяти, если новый размер меньше старого, что приведет к утечкам. Лучше использовать какой-нибудь метод типа erase_item для каждого элемента. Но это забегая вперед.

    6) Метод clear тоже самое. Даже массив не очищает.

    7) Ну и чтобы было чем заняться после прикручивания шаблона - итератор.

    8) P.S. Ыыыыы:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    #ifndef __STDARG_H
    #include <stdarg.h>
    #endif
     
    IntVector::IntVector( int count, int item, ... ) : size(0), capacity(count)
    {
        mas = new int[count];
     
        va_list p;
        va_start( p, count );
     
        while( count-- )
          this->pushBack( va_arg( p, int ) );
     
        va_end(p);
    }
    За заполнение вектора списком без примочек одиннадцатого стандарта многие б сказали спасибо.
    Запись от SatanaXIII размещена 02.07.2014 в 14:33 SatanaXIII вне форума
  2. Старый комментарий
    Цитата Сообщение от SatanaXIII
    Некоторые пункты подправила, спасибо.
    По поводу resize и clear - совсем непонятно. Никаких утечек там не предвидится. С чего Вы взяли?
    Запись от Тамика размещена 02.07.2014 в 15:04 Тамика вне форума
  3. Старый комментарий
    Аватар для SatanaXIII
    Цитата Сообщение от Тамика
    Никаких утечек там не предвидится.
    А что будет, если в данный вектор положить не целые числа, а, к примеру, объекты некоего класса, захватывающие при инициализации ресурсы? Освободятся ли они, если просто о них забыть?
    P.S. Метод popBack кстати в ту же кучу.
    Запись от SatanaXIII размещена 02.07.2014 в 16:19 SatanaXIII вне форума
  4. Старый комментарий
    Аватар для SatanaXIII
    Хотя нет. Я не прав. Всем этим должен заниматься кончено же деструктор.

    Но метод swap, выполненный через std::swap, это конечно лихо.
    Запись от SatanaXIII размещена 02.07.2014 в 16:50 SatanaXIII вне форума
  5. Старый комментарий
    Цитата Сообщение от SatanaXIII
    Хотя нет. Я не прав. Всем этим должен заниматься кончено же деструктор.

    Но метод swap, выполненный через std::swap, это конечно лихо.
    Ну вот.
    А со swap ещё будет беседа. Еще прошлый раз думала написать свой. Но руки не дошли. Так что в следующей серии будет персональный своп.
    Запись от Тамика размещена 02.07.2014 в 16:57 Тамика вне форума
  6. Старый комментарий
    Аватар для Croessmah
    Внесу свою лепту:
    нет const версии at, в результате чего нельзя использовать at у константных объектов:
    C++
    1
    2
    
       const IntVector vec ;
       int value = vec.at(3) ; //Ошибка vec - константный объект
    В циклах сравнивание значения типа int со значением типа size_t. Чем это чревато? Тем, что если в переменной size_t лежит значение больше максимального значения, представимого типом int, то цикл будет бесконечным, т.к. переменная типа int просто будет переполняться и "уходить в минуса". Попробуйте просто для примера:
    C++
    1
    2
    3
    4
    5
    
    int main(){
       size_t f = static_cast<size_t>( std::numeric_limits<int>::max() ) + 1 ;
       for ( int i = 0 ; i < f ; i+=10000 )
          std::cout << i << std::endl ;
    }
    Также, нет ограничения на максимальный размер. Вектор не может быть бесконечным

    В стандартном векторе константные front и back возвращают ссылки на элемент, а не копии объектов:
    C++
    1
    2
    
          const_reference back() const;
    const_reference front() const;

    В конструкторе копий:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    
    IntVector::IntVector(const IntVector& in)
    {
        size = in.size;
        capacity = in.capacity;
        mas = new int[capacity];
        for (int i = 0; i < size; ++i)
            mas[i] = in.mas[i];
    }
    наверное, лучше будет уравнять size и capacity, иначе невозможно будет "обрезать" память как в стандартном векторе с помощью swap'а
    C++
    1
    
    IntVector(vec).swap(vec) ;//capacity не изменяется.
    Усовершенствован конструктор - теперь он не просто принимает размер будущего вектора, а может еще и принимать желаемое значение!
    Можно еще реализовать конструктор, принимающий интервал [begin,end)
    В следующем сезоне "Таня и Вектор" - обобщение класса и превращение его в шаблон.
    С учетом этого нужно было сразу делать, иначе придется почти весь класс переписать. И это относится не только к изменению типа int на T, а придется переосмыслить структуру всего класса
    Запись от Croessmah размещена 06.07.2014 в 20:43 Croessmah вне форума
 
Новые блоги и статьи
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru