해결된 질문
작성
·
326
·
수정됨
2
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
#include <iostream>
#include <initializer_list>
using namespace std;
class IntArray // integer가 담기는 클래스
{
private:
int m_length = 0;
int* m_data = nullptr;
public:
//Constructors 생성자
IntArray(const int array_len)
: m_length(array_len)
{
initialize(m_length);
}
IntArray(const initializer_list<int>& list)
:IntArray(list.size())
{
int count = 0;
for ( auto& ele : list )
{
m_data[ count ] = ele;
count++;
}
}
//initialize() 생성자에서 가져다 쓸 함수
void initialize(int len)
{
m_data = new int[ len ];
}
//Destructors 소멸자
~IntArray()
{
if ( m_data != nullptr )
delete[ ] m_data;
m_data = nullptr;
}
//reset(); 메모리 지우고 초기상태로.
void reset()
{
delete[ ] m_data;
m_data = nullptr;
m_length = 0;
}
//resize(); // 사이즈 바꿈
void resize(int n)
{
// 기존 메모리 temp에 저장
int* temp = m_data;
// n만큼의 메모리 리사이징
m_data = new int[ n ];
// 리사이징된 메모리 크기만큼 기존메모리에서 값의 복사
for ( int i = 0; i < n; i++ )
{
m_data[ i ] = temp[ i ];
}
m_length = n;
// 복사가 완료됐으면 기존 메모리 삭제
delete[ ] temp;
}
void insertBefore(const int& value, const int& ix)
{
// 인서트를 위한 새로운 메모리 할당
int* temp = new int[ m_length + 1 ];
// ix에 값이 들어가므로, temp[ix+1] = m_data[ix]의 전달이 이뤄진다.
for ( int i = ix; i < m_length + 1; i++ )
{
temp[ i + 1 ] = m_data[ i ];
}
// 인서트 인덱스에 value 넣기
temp[ ix ] = value;
// ix 전까지 기존 밸류 복사
for ( int i = ix - 1; i >= 0; i-- )
{
temp[ i ] = m_data[ i ];
}
// 기존 데이터 메모리 삭제
delete[ ] m_data;
// 새롭게 인서트된 메모리 저장
m_data = temp;
// 길이 +1
m_length += 1;
}
void remove(const int& ix)
{
// 제거를 위한 새로운 메모리 공간할당
int* temp = new int[ m_length - 1 ];
// 제거할 인덱스(ix)를 기준으로 값의 paste
// step1. ix전의 값은 정상복사
for ( int i = 0; i < ix; i++ )
{
temp[ i ] = m_data[ i ];
}
// step2. ix기준 우측값의 복사
for ( int i = ix; i < m_length - 1; i++ )
{
temp[ i ] = m_data[ i + 1 ];
}
// 완료됐으면 기존 메모리 삭제
delete[ ] m_data;
// 새로운 메모리 저장
m_data = temp;
// 삭제됐으므로 길이 -1
m_length -= 1;
}
void push_back(const int& value)
{
// 끝자리 추적후에 그 뒤 새로운 메모리공간 할당후 추가하기
// insertBefore(value, m_length)를 하면?
insertBefore(value, m_length);
}
void showAllEle() const
{
cout << "m_length: " << m_length << endl;
cout << "m_data: ";
for ( int i = 0; i < m_length; i++ )
{
cout << m_data[ i ] << " ";
}
cout << endl;
}
};
int main()
{
IntArray my_arr{1,3,5,7,9};
my_arr.showAllEle();
my_arr.insertBefore(10,1);
my_arr.showAllEle();
my_arr.remove(3);
my_arr.showAllEle();
my_arr.push_back(13);
my_arr.showAllEle();
}
살짝 지저분하지만, 구현에 목적을 두고 최대한 해봤는데 일단 원하는대로 구현이 되는건 확인했습니다.
추가로 문제가 발생할 수 있거나 아쉬운 부분 피드백을 해주세요! 더 정확하고 깔끔하게 다시 수정해보겠습니다.
또한, 마지막 push_back 함수는 insert랑 기능상 비슷해보여서 insert함수를 재활용했는데 이 방법또한 괜찮은것인지 아니면 위험한것인지도 답변해주시면 감사합니다
답변 1
1
안녕하세요, 답변 도우미 Soobak 입니다.
우선, 코드 리뷰는 그 범위가 넓고 다양해서 인프런 답변을 통해 정확히 제공해드리기 어려운 점 양해 부탁 드리겠습니다.
또한, 개인적으로 모든 코드에는 정답이 없다고 생각합니다.
그럼에도, 조금 조언을 해드려보자면 다음과 같습니다.
resize()
: 현재 구현에서는 새로운 크기가 기존 배열의 크기보다 클 경우, 새로 추가된 공간에는 초기화되지 않은 값들이 들어갑니다. 이는 예기지 않은 결과나 버그를 유발할 수 있습니다.
이에 대해서 방법을 고민해보시거나, 직접 STD 의 컨테이너들과 비교해보시면 좋을 것 같습니다.
push_back()
과 insert()
: push_back()
함수의 구현을 위해 insert()
함수를 사용하는 것은 효율적이지 않습니다.
기존 배열의 끝에 요소를 추가하기만 하는 것과, 새로운 배열의 메모리를 모두 할당하고 복사하는 과정은 다르기 때문입니다. 특히, 배열의 길이가 클 수록 더욱 차이가 많이 날 것입니다.
일반적으로 push_back()
함수는 여분의 메모리 공간을 일정 크기까지 할당해두고, 그 크기가 더 이상 남아있지 않을 때만 새롭게 메모리를 할당하는 것으로 알고 있습니다.
직접 STD 의 헤더를 통해 구현부의 코드가 어떻게 작성되어 있는지 참고해보시거나, 검색을 통해 공부를 해보시는 것도 좋은 방법 일 것 같습니다.
여러 함수에서 동일한 로직(예 : 메모리 할당, 배열 복사)이 반복적으로 사용됩니다. 이러한 로직을 별도의 함수로 분리하여 코드의 중복을 줄이면 가독성이 더 좋아질 것 같습니다.
여러 예외들에 대한 처리에 대해서 고민해보셔도 좋을 것 같습니다. (예 : m_data
가 nullptr
인 경우에 대한 예외 처리)
끝으로, 저도 STD 의 vector
, stack
, set
, map
등을 직접 다시 구현하며 공부해본 적이 있는데요,
그 때 당시 질문자님 처럼 스스로 코드를 작성해본 후, 각 컴파일러들이 구현한 STD 의 컨테이너의 코드와 비교해보는 과정에서 다양한 차이점들과 스스로 생각하지 못했던 부분, STD 에 구현된 코드의 이유 등을 이해하려 학습했던 과정이 큰 도움이 됐던 기억이 납니다.
STD 의 코드들은 컴파일러 헤더의 구현부를 참고해보시거나, 검색을 통해서도 쉽게 찾으실 수 있으니 이를 활용해보시는 것도 추천드립니다.
모두 개인적인 의견이므로, 질문자님께 맞는 공부 방법은 스스로 생각해보시는 것이 가장 좋은 것 같습니다.
열정적으로 공부하시는 것이 글에서 느껴져서 인상 깊네요.
화이팅! 👍👍
감사합니다. 이렇게라도 글을 남겨야 부족한 점이 명확하게 보이는 것 같습니다.. 화이팅!