이번에 알아볼 것은 바로 CArray 클래스 입니다.

일단 32bit(4Byte) 환경이라고 미리 이야기를 하겠습니다. 그래야 포인터 개념에 대한 설명이 맞기 때문이죠.

시간이 흐르면 64bit(8Byte) 많이 쓰게 될 텐데 그때 가서 포인터 크기가 왜 저래요... 이런 소리 하시면 완전 곤란함 ㅡ_ㅡㅋ

 

CArray는 MSDN을 검색하면 다음과 같은 정보를 얻을 수 있죠.

 

template < class TYPE, class ARG_TYPE = const TYPE& > 
class CArray : 
   public CObject

 

여기서 첫 번째 매개변수는 배열에 저장된 객체의 데이터 타입, 두 번째는 배열에 저장된 객체에 접근하기 위해 사용하는 인수 타입~

그냥 저걸 통째로 받아들여서 이해할 수 있는 아름다운 머리를 가지신 분들도 있겠지만, 그렇지 못한 분들을 위해서 좀 더 쉽게 설명하면

어떤 데이터를 저장하는(첫 번째 매개변수) 배열(배열의 객체를 지시할 수 있는 두번째 매개변수)을 선언하는 것입니다.

 

MSDN 설명 중 첫 줄 설명이 아름답네요.

 "Supports arrays that are similar to C arrays, but can dynamically shrink and grow as necessary."

CArray라고는 하지만 결국 이 놈은 배열이고 필요에 의해 늘었다가 줄었다가 한다.

이런 기능을 클래스의 개념으로 접근하기 때문에 멤버 함수를 이용하면 쉽게 관리가 가능한 것이다.

 

아래의 그림을 보면 이해가 더 쉬울 겁니다.

 


 

① char 배열이다. 이건 쉬울 것 같다. "char abc[12];" 얘랑 뭐가 다를까? 같다.

    char 데이터를 가지고, 여기에 접근하는건 char에 접근하기 위한 주소 연사자인 &를 이용하여 각 값에 접근을 할 수 있다.

 

② char 포인터 배열이다. 32bit OS 사용중이라면 주소 값은 4Byte 값을 지닌다.
    즉 char 형 데이터가 들어가 있는 주소를 포인팅 하기 위해서는 4Byte가 필요한 것이다.
    실제 값은 1Byte 값을 가지지만 주소를 가리키는 포인터 개념과 헷갈리면 안되겠다.
    이런 포인터가 모여있는 배열에 대해서는 해당 포인터를 포인팅 하도록 선언해서 쓰면 되겠다.

 

③ int 배열이다. ①과 같다. 단지 4Byte를 쓴다는 차이점이 있을 뿐이다. 이렇게 설명하면 어려운가? 어려우면 참말로 난감.. ㅡ_ㅡㅋ

    참고로 MSDN은 절대로 이렇게 설명 안해준다. 머리가 좋으면 손발이 덜 고생한다던데... 그래서 내가 이 고생을....

 

 

만약 여기까지 이해가 안 간다면 밑에를 참고하기 바랍니다.

여기 오기 전에 다 이해하셨길 바라지만... 현실은 그렇게 녹녹치가 않으니깐...

 

솔찍히 MSDN의 글만 보고는 제 머리 능력으로는 전혀 이해 안 가는 부분이 더러 있습니다. ㅡ_ㅡㅋ

 

그래 C 언어에서 배열 쓴거야 뭐 어렵겠어? 그냥 데이터 타입 맞춰서 그냥 생각한 개수만큼 선언해서 쓰면 되잖아.

좋다 이거야~ 이게 필요에 의해서 늘릴 수도 줄일 수도 있다니.. 좋지 좋아~ 암 그렇구 말고.

 

하지만....

 

이건 뭐냔 말이닷 ㅡ_ㅡㅋ

왠지 이걸 접하니깐 딱 하기가 싫어지는군요. 말투부터가...

 

template < class TYPE, class ARG_TYPE = const TYPE& > 
class CArray
   public CObject

 

자.. 일단 템플릿(template) 나왔다. 그래서 그냥 이유 없이 맘에 안 든다. 딱 저 단어로 시작한다는 것 자체가 보기가 싫어진다. 공감?

하지만 포기하지 말자. 그러자고 지금 이 짓을 일삼는 거니깐~

 

그럼 템플릿이 뭔지 알아야 하잖아.....

근데 CArray가 왜 저따구로 쓰는지가 궁금한건지 당장 템플릿까지 다 알 수는 없지 않겠어?

그래서.... 템플릿 개념만 짚어 보고 살짝꿍 넘어가보자. 막상 돌아와서 보니... 길다. 쩝.

 

 

1. 템플릿 : 로직이 같은 경우에 타입을 자유롭게 변환 시켜주는 기능!

 

자... 갈수록 미궁에 빠져든다. 하지만 개념 자체는 쉽다.

예를 들어 x + y라는 함수를 만드는 것에 대해서 생각해 보자.

사람은 x 값과 y 값이 정수든 실수든 더블형이든 그런건 따질 필요 없다.

1+1은 2라는걸 알고 1.5 + 1.5는 3이라는걸 안다.

 

하지만 컴퓨터는 블로그에서 누차 이야기 한 것 같은데 바보다. 하나부터 열까지 알아 먹게끔 설명 다 해줘야 그렇게 처리를 한다.

위와 같은 연산을 수행하려면 1+1은 이게 정수의 덧셈 연산이라고 미리 선언을 해 줘야하고,

1.5+1.5는 이게 소수점을 포함하는 데이터형을 선언한 덧셈 연산을 수행해야 한다고 미리 각각 정의를 해 줘야 한다.

결국 이런 것이다.

 

int add(int a, int b) {

   return a+b;

}

 

double add(double a, double b) {

   return a+b;

}

 

char add(char a, char b) {

   return a+b;

}

 

고작 a + b 하면 되는건데 이것들이 데이터 형이 다르면 함수 호출 자체를 못할 수 있다는 것이다.

물론 말이 여기는 Integer 형과 Double형 char형이지 다른 타입도 추가될 수 있는 문제다.

그런데 그때마다 저걸 굳이 다 저렇게 일일이 이야기 해주는건 얼마나 효율적이지 못한 플레이인가.

 

이런 어벙한 짓을 일삼지 못하도록 뭔가 좀 똑똑해지게 만들 수 없을까?

intdouble 등의 데이터형만 다르지 결국 로직 자체는 다 똑같지 않은가....

 

그래서 템플릿이라는걸 쓰는 것이다.

 

템플릿은 저 위에 설명대로 덧셈을 한다는 똑같은 로직에 데이터의 타입만 다를 뿐이다.

그러니 저렇게 힘들이지 말고 쉽게 가자는 거다. 이왕이면 시간도 줄이고 노동도 줄이고 좋으니까 말이다.

 

그래서 이런걸 가능하게끔 하는걸 템플릿. 즉, 본 뜨는 공구, 형판... 뭐 쉽게 표현하면 초딩때 쓰던 모양자의 역할을 한다.

모양자 얼마나 편한가? 사각형 모양자 하나 있으면 정해진 여러가지의 사각형 모양을 다 그릴 수 있다.

삼각형 그리려면 삼각형 모양자 하나면 또 다양한 삼각형을 만들 수 있다.

 

로직은 4개의 변으로 구성되는 면이냐 3개의 변을 가지는 면이냐는 것이다.

그게 안에 어떤 색을 칠할지는(자료형) 그때 상황 봐서 쓰면 되는 것이다.

단, 여기서 상황 판단은 바보 CPU가 아니라 바로 컴파일러가 하는 것이다.

프로그램 소스를 해석하는 과정에서 컴파일러는 이걸 가능하도록 변수에 맞추어 함수를 만들어 준다.

 

 

2. Templete 사용방법

 

그럼 저 위에껄 어떻게 쓸 수 있을까? 일단 방법 정도는 익혀주는게 저걸 만든 사람에 대한 예의가 아닐까?

 

template <typename T>

T add(T a, T b) {

   return a + b;

}

 

여기서 위 함수들과 차이점이라고 한다면, 리턴 자료형과 인수의 자료형이 서로 정의가 안되어 있고 템플릿 T로 선언되었다는 점이다.

즉, 아직 정해진게 없다는 이야기다. 컴파일러가 보고 필요한 데이터형에 맞는 템플릿 함수를 생성하여 사용하되,

중복적으로 같은 데이터형을 이용하는 경우 미리 생성한 템플릿 함수를 사용하도록 한다.

 

T를 int로 쓸지 double로 쓸지 char로 쓸지에 대해서 컴파일러가 그때 상황봐서 만들어서 써라~

이렇게 생각하면 된다. 단지 저렇게 한 줄 더 추가하면 매개변수 데이터형이 달라져도 바로 사용을 할 수 있게 된다.

 

앗 여기서~

특별한 케이스~

즉 특별한 데이터 형에 대해서는 특별하게 처리해줄 필요가 있을 때에도 템플릿을 쓸 수 있다.

그래서 아래와 같이 특별한 데이터형이 들오어는 케이스, 즉 문제의 발단인 원래 CArray에 대해서 다시 생각해 보자.

 

 

3. 그래서 결국 template < class TYPE, class ARG_TYPE = const TYPE& >이 도대체 뭐냐고 ㅡ_ㅡ;

 

template < class TYPE, class ARG_TYPE = const TYPE& > 
class CArray
   public CObject

 

첫번째 class TYPE은 배열에서 저장되는 객체의 타입 형태를 넣어 주고,

두번째 class ARG_TYPE = const TYPE&는 집어 넣을때 배열의 데이터에 접근하기 위한 데이터 형에 대한 주소연산자입니다.

따라서 배열을 쓰기는 하는데 위와 같은 형태로 선언된 배열을 쓰겠다는 거죠.

그래서 제일 처음 이야기 했던 그림이 나오는 거죠.

 

템플릿에 대해서는 좀 더 많이 다뤄야 하는 부분이고, 저도 사실 아는 바가 이것밖에 없으며,

템플릿 하나 만으로도 성경 같은 책이 나올 수 있는 분야이기 때문에 더 자세한건 참고서적 또는

인터넷 검색을 활용해 보시는게 더 좋을 듯 싶습니다.

 

 

4. 정리

 

CArray도 결국 배열입니다. 근데 사용하기 편리한 배열입니다. 줄이고 늘리고 하는걸 쉽게 할 수 있도록 돕는 클래스죠.

그래서 어떤 데이터를 넣고 어떻게 접근한지에 대해서 선언해서 쓰면 됩니다.

 

※ 참고로 포인터 배열은 CPtrArray 클래스를 사용하면 됩니다.

차이점은 단순히 포인터 객체를 선언한 다음에 포인터 추가시 저장하고자 하는 포인터 타입에 대한 타입캐스팅을 해서 넣으면 됩니다.

그려서 설명하고 싶지만 귀차니즘이 마구 밀려오네요. 위 그림 2번 참고하시면 될 듯 합니다.

포인터에 대한 캐스팅 타입이 다른 것도 들어간다는 점이죠.

Posted by duki 두기

블로그 이미지
개인적인 잡다한 기록 공간입니다
duki 두기

공지사항

Yesterday
Today
Total

달력

 « |  » 2024.5
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함