Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 클래스 내부에 동적 2D 배열을 만드는 방법


C++에서는 클래스 내부에 배열을 캡슐화하고 연산자 오버로딩을 활용하면, 일반 배열처럼 [] 연산자로 요소에 접근하면서도 범위 검사 같은 안전장치를 갖춘 배열 클래스를 손쉽게 구현할 수 있습니다. 아래 예제는 클래스 안에 배열을 정의하고, 생성자에서 모든 요소를 초기화한 뒤 화면에 출력하는 간단한 프로그램입니다.

알고리즘

시작
   Arr 클래스를 생성하고 배열의 최대 크기를 선언한다.
   생성자에서 전달받은 크기와 초기값을 이용해 for 루프로 모든 요소를 초기화한다.
   [] 연산자를 오버로딩하여 범위를 검사한 후 요소에 접근한다.
   모든 요소를 순회하며 출력한다.
종료.

예제 코드

#include <iostream>
#include <stdlib.h>
using namespace std;
const int M=7;
class Arr {
    private:
    int A[M];
    int size;
    public:
    Arr(int s, int v) {
       if(s>M) {
           cout<<endl<<"This is beyond maximum size";
           exit(1);
       }
       size = s;
       for(int i=0;i<size;i++)
           A[i] = v;
    }
    int& operator[](int i) {
       if( (i<0) || (i >= size) ) {
           cout<<endl<<"Error: Array out of bound";
           exit(1);
       }
       return A[i];
    }
};
int main() {
    int i=0;
    Arr a(7,0);
    for(i=0;i<7;i++)
        a[i] = i*10;
    cout<<"Array elements are:"<<endl;
    for(i=0;i<7;i++) {
        int val = a[i];
        cout<<val<<endl;
    }
   return 0;
}

실행 결과

Array elements are:
0
10
20
30
40
50
60

코드 핵심 포인트

1. 생성자를 통한 초기화
Arr(int s, int v) 생성자는 배열의 실제 사용 크기(s)와 초기값(v)을 전달받습니다. 요청된 크기가 상수 M(최대 크기)을 초과하면 프로그램을 종료하여 잘못된 메모리 접근을 미리 방지합니다.

2. operator[] 오버로딩
int& operator[](int i)를 정의하면 객체를 마치 일반 배열처럼 a[i] 형태로 사용할 수 있습니다. 참조(&)를 반환하기 때문에 값을 읽는 것뿐 아니라 a[i] = i*10;처럼 대입도 가능합니다.

3. 범위 검사를 통한 안전성 확보
인덱스가 0보다 작거나 size 이상이면 "Array out of bound" 오류를 출력하고 프로그램을 종료합니다. 일반 배열에서 발생하기 쉬운 버퍼 오버플로우 문제를 클래스 차원에서 차단하는 것입니다.

2차원 배열로 확장하기

이 패턴은 2차원 배열로도 자연스럽게 확장할 수 있습니다. 내부 멤버를 int** A;와 같은 이중 포인터로 선언하고, 생성자에서 행마다 new int[cols]로 동적 할당한 뒤, operator[](int row)가 해당 행의 포인터를 반환하도록 하면 a[i][j] 형태의 접근이 가능합니다. 단, 소멸자에서 반드시 delete[]로 할당된 메모리를 해제해야 메모리 누수를 막을 수 있습니다.