안선생의 개발 블로그

C++ erase 본문

C++

C++ erase

안선생 2022. 9. 5. 20:45

erase 추가에서 완성한 가변배열

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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#pragma once
#include <assert.h>
#include <iostream>
using namespace std;
template<typename T>
class CArr
{
private:
    T* pint;
    int count;
    int maxcount;
public:
    void PushBack(const T& Data); // 
    void resize(int ResizeCount);
    void Sort();
    T* data() { return pint; }
    int size() { return count; }
    int capacity() { return maxcount; }
    
    T& operator[] (int idx); // operator를 써줘야함
    class iterator;
    iterator begin();
    iterator end();
    iterator erase(iterator& ear);
 
    void clear() { count = 0; } // 첫칸부터 채워짐
 
public:
    CArr();
    ~CArr();
    //클레스 안에 클레스 = 이너 클래스
    // inner 클래스를 포함하고있는 클래스의 private 접근 가능
    class iterator // 우리가 만든 가변배엘에 데이터들을 가르키게 할 수 있게 만듦
    {
    private:
        //백터가 넘쳐서 새로 재활당 될경우 백터자체에 주소를 알아야함
        CArr* cpint; // iterator 가 가리킬 데이터를 관리하는 가변배열 주소
        T*  ipint; //데이터의 시작주소
        int index; //몇번째를 가르키고 있는지 idex
        bool bvaili; // iterator 유효성 체크
 
    public:
        T& operator *()
        {
            //iterator가 알고있는 주소와, 가변배열이 알고 있는 주소가 달라진 경우(공간 확장으로 주소가 달라진 경우)
            // iterator가 end iterator 인 경우
            if (cpint->pint != ipint || index == -1 || bvaili == false)
            {
                assert(false);
            }
            return ipint[index];
        }
 
        //전위
        iterator& operator ++()
        {
            // iterator가 알고있는 주소와, 가변배열이 알고 있는 주소가 달라진 경우(공간 확장으로 주소가 달라진 경우)
            if (cpint->pint != ipint || index == -1)
            {
                assert(false);
            }
            // iterator 가 마지막 데이터를 가리키고 있는 경우
            // --> end iterator 가 된다.
            if (cpint->count -1 == index)
            {
                index = -1;
            }
            else
            {
                ++index;
            }
            // end iterator 인 경우
            
 
            
            return *this;
        }
 
 
        // ++ 후위
        iterator operator ++(int)// &복사본을 호출하면 이미 실행되기 때문 int는 아무 의미 없음
        {
            
            iterator copyiter = *this//this는 호출한 객체
 
            ++(*this);
 
            return copyiter;
        }
 
        iterator& operator --()
        {
 
            return *this;
        }
 
        // 비교ㅕ연산자 ==, !=
        bool operator == (const iterator& other)
        {
            
            if (ipint == other.ipint && index == other.index)
            {
                return true;
            }
            return false;
        }
 
        bool operator != (const iterator& other)
        {
            return !(*this == other); // 위에 == 함수 반대로 한것
        }
    public:
        iterator()
            :cpint(nullptr)
            ,ipint(nullptr)
            ,index(-1)
            , bvaili(false)
        {
        }
        iterator(CArr* cpint,T* ipint, int index)
            :cpint(cpint)
            ,ipint(ipint)
            , index(index)
            ,bvaili(false)
        {
            if (nullptr != cpint && 0 <= index)
            {
                bvaili = true;
            }
        }
        ~iterator()        
        {
            //delete[] cpint;
            //delete[] ipint;
            //index = -1;
        }
 
        friend class CArr; // private를 사용할 수 있게 해줌
    };
};
 
template<typename T>
CArr<T>::CArr()  // T자료형안에 선언되있는 클래스 <T>를 지정해줘야함
// 클래스 선언 범위 밖에서 지정했기때문에 CArr클래에 지정되어있는 생성자라는 뜻
    //이니셜라이저로 초기화
    : pint(nullptr)
    , count(0)
    , maxcount(2)
    
{
    pint = new T[2]; // new 새로운 C++동적활당 malloc 이랑 같음 
    // int2개만큼 할당
 
}
template<typename T>
CArr<T>::~CArr()
{
    //delete 동적할당 해제 free랑 같음
    for (int i = 0; i < count; i++)
    {
        //cout << pint[i] << endl;
    }
    delete[] pint; // 위에 인트 자료형을 여러게 선언했기 떄문에 []붙여줌 하나만 선언할시 []안붙여도 된다.
    count = 0;
    maxcount = 0;
 
}
template<typename T>
void CArr<T>::PushBack(const T& Data)
{
    if (this->maxcount <= this->count)
    {
        resize(maxcount * 2);
    }
 
    pint[this->count++= Data;
}
template<typename T>
void CArr<T>::resize(int ResizeCount)
{
    //현재 최대 수용량 보다 더 적은 수치로 확장하려는 경우
    if (maxcount >= ResizeCount)
    {
        assert(nullptr);
    }
 
    // 1. 리사이즈 시킬 개수만큼 동적할당 한다.
    T* pnew = new T[ResizeCount];
 
    // 2 기존 공간에 있던 데이터들을 새로 할당한 공간으로 복사시킨다.
    for (int i = 0; i < this->count; i++)
    {
        pnew[i] = this->pint[i];
    }
 
    // 3. 기존 공간은 메모리 해제
    delete[] pint;
 
    // 4. 배열이 새로 할당된 공간을 가리키게 한다.
    this->pint = pnew;
 
    //5 . maxcoyunt 변경점 적용
    this->maxcount = ResizeCount;
 
}
template<typename T>
void CArr<T>::Sort()
{
    if (count < 1)
    {
        return;
    }
 
    while (1)
    {
        
        bool finsih = true;
        for (int i = 0; i < count - 1; i++) {
            if (pint[i] > pint[i + 1])
            {
                int re = pint[i];
                pint[i] = pint[i + 1];
                pint[i + 1= re;
                finsih = false;
            }
        }
        if (finsih == true)
        {
            break;
        }
    }
}
 
 
 
template<typename T>
T& CArr<T>::operator[](int idx)
{
    return pint[idx];
}
 
template<typename T>
//typename적어준 이유는 이너클래스인 경우 반환내용이 iterator인것을 알려주기위해
typename CArr<T>::iterator CArr<T>::begin()
{
    if (count == 0)
    {
        return iterator(thisthis->pint, -1); //데이터가 없는 경우, begin() == end()
    }
    // 시작을 가리키는 iterator 를 만들어서 반환해줌
    //iterator iter(this->pint, 0);
    return iterator(thisthis->pint, 0); //임시객체라고 해서 변수명을 안짖고 바로 만들어줌
 
    /*iterator iter;
 
    iter.cpint = this;
    iter.ipint = this->pint;
    iter.idx = 0;*/
    /*return iter;*/
}
 
 
template<typename T>
typename CArr<T>::iterator CArr<T>::end()
{
    
    return iterator(thisthis->pint, -1); //임시객체라고 해서 변수명을 안짖고 바로 만들어줌
}
 
template<typename T>
typename CArr<T>::iterator CArr<T>::erase(iterator& ear)
{
    //iterator 가 다른 Arr 쪽 요소를 가리키는 경우
    //iterator 가 end iterator 인 경우
    if (ear.cpint != this || end() == ear || count <= ear.index)
    {
        assert(nullptr);
    }
 
    //반복횟수는 count값에서 삭제인덱스 +1 을 빼준다.
    //iterator 가 가리키는 데이터를 배열 내애서 제거한다.
    int loopcount = count - (ear.index + 1);
 
    for (int i = 0; i < loopcount; i++)
    {
        pint[i + ear.index] = pint[i + ear.index + 1];
    }
    ear.bvaili = false;
    //카운터 감소
    count--;
 
    return iterator(this,pint,ear.index);
}
 
cs

 

 

출처 : https://www.youtube.com/c/AssortRockGameAcademy

'C++' 카테고리의 다른 글

C++ Tree  (0) 2022.09.18
C++ list iterator  (1) 2022.09.13
C++ iterator  (0) 2022.09.02
C++ STL(vector,list)  (0) 2022.08.31
C++ namespace , 입출력 구현  (0) 2022.08.31