C++ - 클래스로 배열 구현하기

이강민·2023년 9월 1일

C++

목록 보기
18/22
post-thumbnail

클래스로 배열 구현하기

Arr.h

클래스를 정의하는 부분을 만든다.
해당 헤더에서 만든 클래스는 추후 멤버메소드를 정의할 때 사용한다.

#pragma once
    class CArr {
        private : 
//해당 변수는 직접 수정 할 수 없도록 private로 정의한다.
//또한 멤버변수의 주소를 참조하기 위해 포인터 변수로 생성한다.s
            int* m_int;
            int m_iCount;
            int m_MaxCount;
    //생성자와 소멸자를 만들어서 최초 초기화 시 원하는 멤버변수의 값을 사용하도록 한다.
        public :
        // 생성자
            CArr();
        //소멸자
            ~CArr();
        // 구현은 Carr.cpp에서 진행한다.
        public : 
// 배열을 추가하는 함수이다. 
            void PushBack(int Data);
// 배열을 추가할 때 공간을 늘려주는 함수이다.
            void resize(int DataCount);
    };

멤버변수 int는 실제 값이 들어갈 변수이고
iCount변수는 들어간 값의 갯수
MaxCount는 현재 들어간 값의 총 갯수를 의미한다.

Arr.cpp

//다른 파일에 있는 클래스 내부에서 가져온 클래스를 정의한다. 
CArr::CArr() :
    m_int(nullptr), 
    m_iCount(0),
    m_MaxCount(0)
    
{
    // new 생성자를 사용하여 m_int에 공간을 할당한다.
    // new로 생성해야 클래스의 크기만큼 공간이 할애된다.
    m_int = new int[2];    
}

CArr::~CArr(){
    //cpp에서는 delete를 사용해서 메로리를 해제하는데 여러개일 경우 []를 붙여서 사용한다.
    // delete를 붙여서 주소가 연속적이라는 것을 알려준다.
    delete[] m_int;
}
    
void CArr::PushBack(int Data){
    //this 생략 가능하다. 
    //힙 영역 공간이 다참
    if(this->m_MaxCount <= this->m_iCount){
        //재할당
        resize(m_MaxCount * 2);
    }
    //데이터 추가
    this->m_int[this->m_iCount++] = Data;
}

void CArr:: resize(int DataCount){
    // 추가하려는 데이터가 현재 데이터 갯수보다 작거나 같으면 의미가 없다.
    if(this->m_MaxCount >= DataCount){
        assert(this->m_MaxCount >= DataCount);
    }
    //리사이즈 시킬 갯수만큼 동적할당
  // 멤버변수에 주소값을 전달하여 pNew를 사용하기 위해 포인터 변수로 공간을 생성한다.
    int* pNew = new int[DataCount];
    //기존 공간 데이터들을 새로 할당된 공간으로 복사
    for(int i =0; i< m_iCount; ++i){
        pNew[i] = m_int[i];
    }
    // 기존 공간 삭제
    delete[] m_int;
    //배열이 새로 할당된 공간을 가르킨다.
    m_int = pNew;
    //MaxCount 변경점 적용
    m_MaxCount = DataCount;
}

main.cpp

#include <iostream>
#include "Arr.h"
int main() {
    
    //c++동적할당 new, delete
    //기존은 malloc과 free는 내가 순수하게 요청한 것만 크기를 할당하였다.
    CArr carr;
    carr.PushBack(10);
    carr.PushBack(20);
    carr.PushBack(30);
    //소멸자를 호출하여 메모리에서 자동 해제 한다.
   
    return 0;
}

이제 데이터를 넣고 관리하는 클래스가 완성되었다.
그러나 일반적인 배열처럼 동작하지 않는다. 우리가 원하는 것은 배열과 같이 carr[1]도 사용가능하고 carr[1] = 1; 처럼 값을 할당 할 수도 있어야 한다. 클래스의 오퍼레이션 연산자를 통해서 만들어보자

Arr.h


    #pragma once
    
    class CArr {
        private : 
            int* m_int;
            int m_iCount;
            int m_MaxCount;
    
        public :
        // 생성자
            CArr();
        //소멸자
            ~CArr();
        // 구현은 Carr.cpp에서 진행한다.
        public : 
            void PushBack(int Data);
            void resize(int DataCount);
          // 오퍼레이션 연산자 추가하기 
            void operator[] (int idx);
    };

Arr.cpp

오퍼레이션 연산자를 정의한다.
레퍼런스로 값을 전달해야 즉시 수정할 수 있는 배열 할당이 가능하다.

//주소로 전달하면 역참조하여서 원본 배열을 수정 할 수 있다.
//레퍼런스로 전달해야 해당 값을 즉시 수정이 가능하다.
int& CArr::operator[](int idx){
// []를 사용하면 m_int[idx]를 실행시켜라. 
    return m_int[idx]; 
}

main.cpp

오퍼레이션 연산자를 추가하면 다음과 같은 동작이 가능하다.

#include <iostream>
#include "main.h"

int main() {
    
    //c++동적할당 new, delete
    //기존은 malloc과 free는 내가 순수하게 요청한 것만 크기를 할당하였다.
    CArr carr;
    carr.PushBack(10);
    carr.PushBack(20);
    carr.PushBack(30);
    //소멸자를 호출하여 메모리에서 자동 해제 한다.

    //원래 객체의 배열을 호출 할 때 다음은 실행되지 않는다.
    // carr[0];
    //그러나 연산자 함수를 만들어서 임의로 만들어 줄 수 있다. 
    int dataArr = carr[2];
    carr[2] =530;
    std::cout<<carr[2]<<std::endl<<dataArr <<std::endl;
    
    return 0;
}

출력문을 통해 결과를 보면 최초 클래스 메소드를 이용하여 배열을 추가하고 해당되는 배열의 자리를 530 값을 추가하니 즉시 값이 반영된 것을 알 수 있다.

profile
AllTimeDevelop

0개의 댓글