• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

IntArray 클래스를 구현해봤는데 피드백 부탁드립니다.

23.10.07 17:29 작성 23.10.07 17:31 수정 조회수 216

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님의 프로필

Soobak

2023.10.07

안녕하세요, 답변 도우미 Soobak 입니다.

우선, 코드 리뷰는 그 범위가 넓고 다양해서 인프런 답변을 통해 정확히 제공해드리기 어려운 점 양해 부탁 드리겠습니다.
또한, 개인적으로 모든 코드에는 정답이 없다고 생각합니다.
그럼에도, 조금 조언을 해드려보자면 다음과 같습니다.

  • resize()
    : 현재 구현에서는 새로운 크기가 기존 배열의 크기보다 클 경우, 새로 추가된 공간에는 초기화되지 않은 값들이 들어갑니다. 이는 예기지 않은 결과나 버그를 유발할 수 있습니다.
    이에 대해서 방법을 고민해보시거나, 직접 STD 의 컨테이너들과 비교해보시면 좋을 것 같습니다.

     

  • push_back()insert()


    : push_back() 함수의 구현을 위해 insert() 함수를 사용하는 것은 효율적이지 않습니다.


    기존 배열의 끝에 요소를 추가하기만 하는 것과, 새로운 배열의 메모리를 모두 할당하고 복사하는 과정은 다르기 때문입니다. 특히, 배열의 길이가 클 수록 더욱 차이가 많이 날 것입니다.
    일반적으로 push_back() 함수는 여분의 메모리 공간을 일정 크기까지 할당해두고, 그 크기가 더 이상 남아있지 않을 때만 새롭게 메모리를 할당하는 것으로 알고 있습니다.
    직접 STD 의 헤더를 통해 구현부의 코드가 어떻게 작성되어 있는지 참고해보시거나, 검색을 통해 공부를 해보시는 것도 좋은 방법 일 것 같습니다.

 

  • 여러 함수에서 동일한 로직(예 : 메모리 할당, 배열 복사)이 반복적으로 사용됩니다. 이러한 로직을 별도의 함수로 분리하여 코드의 중복을 줄이면 가독성이 더 좋아질 것 같습니다.

 

  • 여러 예외들에 대한 처리에 대해서 고민해보셔도 좋을 것 같습니다. (예 : m_datanullptr 인 경우에 대한 예외 처리)

 

끝으로, 저도 STD 의 vector , stack , set , map 등을 직접 다시 구현하며 공부해본 적이 있는데요,
그 때 당시 질문자님 처럼 스스로 코드를 작성해본 후, 각 컴파일러들이 구현한 STD 의 컨테이너의 코드와 비교해보는 과정에서 다양한 차이점들과 스스로 생각하지 못했던 부분, STD 에 구현된 코드의 이유 등을 이해하려 학습했던 과정이 큰 도움이 됐던 기억이 납니다.

STD 의 코드들은 컴파일러 헤더의 구현부를 참고해보시거나, 검색을 통해서도 쉽게 찾으실 수 있으니 이를 활용해보시는 것도 추천드립니다.

모두 개인적인 의견이므로, 질문자님께 맞는 공부 방법은 스스로 생각해보시는 것이 가장 좋은 것 같습니다.


열정적으로 공부하시는 것이 글에서 느껴져서 인상 깊네요.
화이팅! 👍👍

Yookpo님의 프로필

Yookpo

질문자

2023.10.08

감사합니다. 이렇게라도 글을 남겨야 부족한 점이 명확하게 보이는 것 같습니다.. 화이팅!