inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

홍정모의 따라하며 배우는 C++

10.6 컨테이너 클래스

컨테이너 클래스 피드백 부탁드립니다.

126

구병주

작성한 질문수 2

1

 

#include <iostream>

#include <vector>

using namespace std;

class IntArray {

private:

int m_length = 0;

int* m_data = nullptr;

public:

//생성자

IntArray(const std::initializer_list<int> &list)

:m_length(list.size()){

m_data = new int[m_length];

int i = 0;

for (auto n : list) {

m_data[i++] = n;

}

}

//copy constructor

IntArray(const IntArray& copy)

:m_length(copy.m_length){

for (int i = 0; i < m_length; i++) {

m_data[i] = copy.m_data[i];

}

}

IntArray operator = (const IntArray source) {

if (this == &source) {

return *this;

}

delete[] m_data;

m_length = source.m_length;

if (source.m_data != nullptr) {

m_data = new int[m_length];

for (int i = 0; i < m_length; i++) {

m_data[i] = source.m_data[i];

}

}

else {

m_data = nullptr;

}

return *this;

}

friend ostream& operator<<(ostream& out, IntArray& arr) {

for (unsigned i = 0; i < arr.m_length; i++) {

out << arr.m_data[i] << " ";

}

out << endl;

return out;

}

//reset

void reset() {

delete[] m_data;

m_length = 0;

m_data = nullptr;

}

//resize

void resize(int new_length) {

if (m_length == new_length) {

return;

}

int* len = new int[new_length];

int temp = m_length > new_length ? new_length : m_length;

for (int i = 0; i < temp; i++) {

len[i] = m_data[i];

}

delete[] m_data;

m_data = len;

m_length = new_length;

}

void insertBefore(const int& pushNum, const int& indexNum) {

if (indexNum<0 || indexNum > m_length) {

return;

}

int* temp = new int[m_length + 1];

for (int i = 0; i < indexNum; i++) {

temp[i] = m_data[i];

}

temp[indexNum] = pushNum;

for (int i = indexNum; i < m_length; i++) {

temp[i + 1] = m_data[i];

}

delete[] m_data;

m_data = temp;

++m_length;

}

void remove(const int& indexNum) {

if (indexNum<0 || indexNum >= m_length) {

return;

}

int* temp = new int[m_length - 1];

for (int i = 0; i < indexNum; i++)

{

temp[i] = m_data[i];

}

for (int i = indexNum + 1; i < m_length; i++) {

temp[i - 1] = m_data[i];

}

delete[] m_data;

m_data = temp;

--m_length;

}

void push_back(const int& num) {

resize(m_length + 1);

m_data[m_length - 1] = num;

}

//소멸자

~IntArray()

{

if (m_data != nullptr) {

reset();

}

}

};

int main()

{

//초기화

IntArray my_arr{ 1,3,5,7,9 };

cout << my_arr << endl;

// 10을 인덱스 1앞에 : 1, 10, 3, 5, 7, 9 출력까지

my_arr.insertBefore(10, 1);

cout << my_arr << endl;

// 인덱스 3 제거, 메모리 제거까지? 1 10 3 7 9

my_arr.remove(3);

cout << my_arr << endl;

// 사이즈 추가? 1 10 3 7 9 13

my_arr.push_back(13);

cout << my_arr << endl;

return 0;

}

insertBefore, remove에서 for문을 두번씩 사용하고 전체적으로 for문으로 많이 사용하는게 좀 걸리긴하는데 더 나은 방법이 있으면 얼마든지 알려주시면 감사하겠습니다!!

c++

답변 1

1

Soobak

안녕하세요? 질문&답변 도우미 Soobak 입니다.

 

과제에서 명시적으로 요구된 내용에서 더 나아가 복사 생성자와 대입 연산자오버로딩까지 챙기며 구현하려 하신 부분이 훌륭하시네요.

다만, 이 과정에서 조금 아쉬운 부분이 있는 것 같습니다.
우선, 복사 생성자에서 메모리 할당이 누락되어 있어 복사 과정에 오류가 발생하게 됩니다.

IntArray(const IntArray& copy)
  :m_length(copy.m_length)
{
  for (int i = 0; i < m_length; i++)
  {
    m_data[i] = copy.m_data[i];    // m_data가 할당되지 않은 상태에서 접근하게 됩니다.
  }
}

: m_data 는 메모리의 할당되어있지 않기 때문에 오류가 발생합니다.

 

또한, 대입 연산자 오버로딩에 있어서 매개변수의 자료형과 반환 자료형이 값으로 되어있는 부분도
참조로 변경하시는 것이 좋습니다. 불필요한 복사 문제와 자기 대입 시 메모리 관리가 엉키는 문제 등을 방지하기 위함입니다.

복사 생성자를 사용하는 코드를 추가하여 프로그램을 실행시켜 보시면 바로 문제점을 쉽게 파악하실 수 있으실 것 같습니다.
(만약, 이해가 어려우시면 강의 9.11 대입 연산자 오버로딩, 깊은 복사, 얕은 복사 부분 를 참고해보시면 도움이 되실 것 같습니다.)

나머지 부분은 잘 구현하셨습니다.
반복문을 많이 사용하시는 부분을 걱정하셨지만, 지금의 학습 단계에서 훌륭하게 작성하셨다고 생각합니다.

추후에 다양한 알고리듬과 자료구조를 학습하시면서 더욱 발전하실 수 있으실 것 같습니다.

 

추가적으로, 더 나은 방법에 대해 궁금증을 갖고 계신 것 같으셔서, 생각난 재밌는 내용을 간단히 소개드려봅니다.

: 컴파일러마다 구현 내용은 조금씩 다르지만, 데이터 추가 가능성이 있는 컨테이너의 경우 최초, 혹은 resize() 를 통한 메모리 할당을 '명시된 크기' 보다 조금 더 많이 할당을 해놓습니다.
따라서, push_back() 혹은 insert() 과정에 있어서 이미 할당된 메모리 공간이 충분하다면 매번 '추가되는 데이터의 개수' 만큼 메모리 할당을 진행하지 않고, 비어있는 메모리 공간에 값을 추가합니다.
그러다가, 비어있는 메모리 공간이 더 이상 없는 경우 또 여유롭게 메모리 할당을 진행합니다.
얼마나 여유롭게 메모리를 할당할지는 컴파일러마다 다르고, 이 과정에 있어서 현재 힙에 할당이 가능한 메모리 공간이 충분한지도 체크하여 예외를 처리하는 등 재미있지만 조금 복잡한 과정 등으로 STL 의 컨테이너들이 구현되고는 합니다. 이외에도 효율성, 최적화를 위해 참 신기하게 구현된 부분이 많으니, 추후 여유가 되신다면 g++ 혹은 clang 등의 컴파일러에서 구현된 STL 의 컨테이너 클래스를 들여다보시는 것도 좋은 학습이 되실 것 같습니다.

응원합니다!

교재 있나요?

1

132

2

11:11 부근에 Something::temp와 Something::getValue의 앞에 &를 붙이는 이유가 뭔가요? (함수 이름은 포인터(주소)가 아닌가요?)

1

87

3

using namespace std; 선언 후에 std::를 하는 이유가 궁금합니다

1

99

2

cstr직접구현

0

115

3

BubbleSort

1

77

2

숙제 마지막 부분

1

78

2

강의와 똑같이 진행했는데 링킹 에러가 발생합니다.

1

92

2

수업할때 레퍼런스로 사용하는 도서는 어떤 도서인가요??

1

160

2

공변반환형 관련 문의 드립니다.

1

89

2

170강 유니크 포인터에대해 질문있습니다

1

79

1

섹션 5 퀴즈의 답이 이상합니다

1

83

2

이중포인터와 배열이 이해가 안됩니다.

1

152

2

5분 17~5분 34초 객체 잘림 질문

1

76

1

Resource.h 코드 알려주세요

1

70

1

char name[] 배열의 길이와 관련해 일부 궁금점이 생겨서 질문합니다

1

93

2

화면좌측 숫자 보이기

1

114

1

화면 좌측 숫자 보이기

0

65

1

처음 c++ 수강하려는데요. 비주얼스튜디오 2022 다운로드해서 설치하면 되는건가요??

1

136

3

46강 string 버퍼 질문입니다

1

80

2

프로그래머스 수열과 구간 쿼리 2 문제 질문입니다.

1

123

2

[] 범위 검사시 assert 사용 관련 질문

1

87

2

Lecture 클래스 멤버변수 명명 관련

0

89

2

프로그래머스의 대소문자 바꿔서 출력하기 문제를 푸는데요

0

73

1

noexcept과 throw()

1

81

2