본문 바로가기
프로그래밍/키워드 정리

[C++] 복습용 키워드 정리 - 9

by Sik.K 2023. 4. 2.

<포인터>

 

C언어에 있는 자료형으로 주소값을 담는 변수이다. int a는 정수를 담는 변수지만 int* b는 int형 변수의 주소를 담는 변수다.

 

따라서 b = a가 성립이 되지 않고 b = &a로 주소값을 담아야 b에 값이 담긴다. 또한 이렇게 주소값을 담고 있기 때문에 b에서 변수 a에 접근이 가능하고 b를 통해 a의 값을 변경할 수 있다.

 

a = 10;

 

*b = 20;

 

위와 같은 코드가 입력이 되면 처음 a에는 10이라는 값이 담겨 있지만 b가 가지고 있는 주소에 접근해 값을 변경하여 20이라는 값을 담았기 때문에 나중에 a의 값을 출력하면 20이라는 값이 나온다.

 

또한 포인터 변수는 주소를 담고 있기 때문에 동적할당에 이용이 된다. C에선 malloc, C++에선 new라는 키워드로 동적할당이 되는데 동적할당한 주소를 포인터 변수에 담겠다는 의미가 되는 것이다.

 

<허상 포인터 / 댕글링 포인터>

 

또한 이렇게 포인터 변수에 동적할당을 하게 되고 후에 동적해제를 해줬다면 반드시 포인터 변수에는 null값을 넣어주어야 한다.

 

값을 해제했을 뿐이지 포인터 변수는 계속 그 메모리 위치를 가리키고 있다. 만약 이 위치에 새로운 값이 할당이 되었고, 여전히 그 값을 포인터 변수가 가리키고 있는 상황에서 위치에 할당된 자료형과, 포인터 변수의 타입이 다를 경우 오류가 발생할 수 있다.

 

이런 포인터를 허상 포인터, 댕글링 포인터라고 한다. 때문에 포인터 변수는 동적해제 후에 반드시 값을 nullptr로 초기화 시켜야 한다.

 

<함수 포인터>

 

함수 또한 주소를 가지고 있다. 우리가 작성한 코드는 컴파일 과정에서 코드 영역에 메모리가 할당이 된다. 때문에 이 주소를 포인터로 지정할 수 있다. 이것을 함수 포인터라고 한다.

 

매개변수와 반환 타입이 없을 경우

void add()
{

}

int main()
{
    void (*fp)();
    fp = add;
    
    return 0;
}

 

매개변수와 반환 타입이 있을 경우

 

int add(int a, int b)
{

}

int main()
{
    int (*fp)(int, int);
    fp = add;
    
    return 0;
}

 

이런 식으로 사용이 가능하다.

 

함수 포인터를 사용하는 이유로는 프로그램의 기능을 유연적으로 사용하기 위함이다. 함수의 이름으로 호출하는 것은 컴파일 단계에서 정해지기 때문에 런타임 도중에 유동적으로 변화가 어렵다.

 

하지만 함수 포인터를 사용해서 함수를 호출하게 되면 동적으로 호출을 할 수 있기 때문에 개발자의 입장에서 유연하게 프로그램을 작성할 수 있고, 프로그램의 가능성을 확장시킬 수 있다.

 

<델리게이트>

 

원래 C++ 언어에서는 없던 개념이고 C#에서 새롭게 생긴 기능이나 UE C++에서도 델리게이트를 사용할 수 있기에 개념을 정리하고자 한다.

 

델리게이트는 한 마디로 대리자라고 설명할 수 있다. 메소드 참조를 포함하고 있는 영역이며 함수를 등록해 두었다가 원할 때 등록된 함수를 호출할 수 있는 기능이다.

 

델리게이트의 특징은 다음과 같다.

 

  • 콜백 함수를 등록하기 위해 C/C++에서 사용한 함수 포인터가 문법이 복잡하고 위험한 방식임에 비해, 간편한 문법과 안전성을 갖춘 대리자를 통해 함수를 호출한다.
  • 동일한 리턴형, 매개변수들을 가진 함수 여러개를 등록하고, 한번에 호출할 수 있다. (발행/구독 패턴의 구현)
  • 호출할 함수나 이를 포함하는 객체가 없어져도 대리자가 체크해 안전하게 처리한다.

 

<콜백(CallBack) 함수>

 

정의를 하면 피호출자가 호출자를 다시 호출하는 것을 의미한다. 대표적인 예시로는 WinAPI의 WinProc 함수이다.

 

좀 더 정확한 설명을 하자면 다음과 같다.

 

호출될 함수를 알려 주어 다른 프로그램 또는 다른 모듈에서 함수를 호출하게 하는 방법. 일반적으로 운영 체계가 호출할 애플리케이션의 함수를 지정해 특정한 사건, 또는 메시지가 발생했을 때 호출될 수 있도록 지정할 수 있다.

 

이것이 콜백 함수의 정의이다.

 

또한 콜백 함수는 다른 함수의 인자로 사용되는 함수를 의미한다.

 

일반 함수와 콜백 함수의 차이점은 '제어권'에 있다. 일반적으로 함수는 조건에 따라 함수를 불러 처리를 하는 식으로 작동한다. 즉, 우리가 어떤 처리가 필요할 때 함수를 호출해 그 처리를 맡기는 것이다.

 

하지만 콜백 함수는 내가 필요할 때 호출해서 사용하는 것이 아니라 특정 이벤트가 발생했을 때 나(사용자)에게 알려달라고 하는 것이다. 즉, 호출 되는 것이라고 생각해야 한다.

댓글