2010년 12월 1일 수요일

new delete로 메모리 할당해주기

C++이 기존의 C보다 더 강력한(효율적인이 맞나?ㅋㅋ)기능중에 하나가 바로 new와 delete이다.

C에서는 free와 malloc을 가지고 메모리 분배를 하였지만 이능 굉장히 비효율적이고 코드의 가독성을 엄청나게 떨어트리는 주범이었다.

이를 극복하기위해 C++에서는 new와 delete라는 명령어가 생겼다. 이름에서도 알수 있듯이 new는 메모리 할당이고 delete는 메모리 회수다 ㅋㅋ

1차원 array일 경우에는 메모리 할당과 회수가 아주 쉽다.
int n = 100;
int *a;
a =  new int [n]
...
delete []a;

2차원일때는 조금 복잡하다ㅋㅋ
int n = 100, m = 200;

//분배 시작
int **a;
a = new int *[m];

for(int i=0; i<m; i++)
{
a[i] = new int [n];
}
//분배완료

...

//회수 시작
for(int i=0; i<m; i++)
{
delete []a[i];
a[i] = NULL;
}

delete []a;
a = NULL;
//회수 완료

똑같은 방법을 사용해서 3,4,5,...차원 array를 정의할수 있다 ㅋㅋ



아 그리고 여기서 분명히 왜 int a[100]이런 방법을 안쓰고 new혹은 malloc을 사용하는게 좋은지 물어보는 사람들이 있을거다. 분명 int a[100] 이라는 방식은 굉장히 편하다. 하지만 이 방법은 공간의 크기를 상수로 정해줄수밖에 없다. 즉
int n = 100;
int a[n];

위와 같은 명령은 에러로 간주된다. 왜냐하면 n은 상수가 아니기 때문이다. 하지만 new나 malloc은 []괄호 안에 꼭 상수를 안 써넣어도 사용할수 있다.






Operator Overload - 연산자 중첩

C++에서 operator overload(연산자 중첩)는 아주 자주 쓰이는 기법이다

 - operator overload란?
C++에 기존에 있는 연산자 부호 +,*,-,++,+=등이 숫자에만 사용되지 않고 임의로 만든 class나 struct에도 사용될수 있도록 하는 기법이다.

- operator overload를 쓰는 이유
연산자 자체의 의미에 맞게 operator overload를 하게되면 코드의 가독성이 높아져 가독성이 높은 코드를 만드는데 큰 도움을 준다.


아무리 이렇게 얘기해봤자 너무 추상적이어서 이해하기 힘들거다. 그래서 얘를 들어보도록 하자.

코딩을 하다가 Vector를 쓸 일이 나와서 아래와 같이 Vector 클래스를 정의하게 됐다.
class Vector
{
public:
...
private:
double e1;
double e2;
};
이 class를 써서 프로그램을 구현하다보면 Vector 더하기,빼기 그리고 Vector간의 내적,외적을 구하는 연산을 진행하게된다. 하지만 모든 함수들을 다 Vector Plus(Vector v1, Vector v2); 이런식으로 구현한다면 코드의 가독성은 굉장히 떨어지게된다. C++에서는 이런 코딩에 대해서 편의를 주기위해 +,-,*등의 부호를 프로그래머 맘대로 정의할수 있게 해준다. 즉 아래와 같은 코드가 의미있도록 프로그래머가 설계할수 있다.
void main(void)
{
Vector v1,v2;
...
Vector v3 = v1+v2;
...
}

그렇다면 이런 코드를 설계하려면 어떻게 해야 하는지 알아보자.
operator overload를 하기 위해서는 operate라는 선언방법을 사용해야 한다.
operator들은 class안에도 선언할수 있고 밖에도 선언할수 있다. 밖에 선언할때는 friend방식으로 선언해야 한다. 아래에서는 비교적 간단한 안에 선언하는 방법에대해서만 설명하겠다.
몇가지 operator의 선언방법은 아래와 같다(Vector class를 얘로 들었을때)
class Vector
{
public:
...
const Vector operator+(const Vector &v) const;
Vector &operator+=(const Vector &v);
double operator*(const Vector &v) const;
Vector &operator=(const Vector &v);
Vector &operator++(void);
const Vector operator++(int);
private:
...
};


'+' operator의 정의함수는 아래와같이 쓸수 있다.
const Vector Vector::operator +(const Vector &v) const
{
Vector temp;
temp.e1 = e1 + v.e1;
temp.e2 = e2 + v.e2;

return temp;
}

이렇게 한 후 main함수에서 v1 = (3,4), v2 = (1,9)  (※주의, 이건 코드가 아닙니다 ㅋㅋ) 이 두 벡터를 아래와 같은 코드로 더하게 되면 v3 = (4,13)이된다.
void main(void)
{
...
v3 = v1+ v2;
...
}

다른 operator들도 똑같은 방식으로 선언하고 정의하여 사용하면 된다.

다른 operator정의의 예는 이 글에 다 쓰지 않고 첨부파일에 붙여놓아야겠다. 글이 너무 길어지면 쓰는 나도 읽는분도 너무 힘드니까 ㅋㅋ

위 operator들을 보면 const,&가 붙는 위치가 뒤죽박죽이다. 다음 글에서는 const와 &가 어떤 규칙으로 붙여지는지 간단하게 설명하도록 하겠다.