-
함수 템플릿과 인라인 함수C++ 언어 2020. 3. 30. 17:01
함수 템플릿이란?
함수 템플릿은 함수의 다중 정의 기능의 단점을 보완 해주는 기능이다. 함수를 다중정의 할 경우 같은 이름의 함수를 반환값, 매개변수 등에 따라 다른 기능을 수행하는 함수로 만드는 것을 말한다. 따라서 함수를 다중정의 할 경우 같은 이름의 함수가 여러개 생기는 것이다.
위와 같이 다중정의 함수를 사용한다면 사용자는 편의성과 확장성을 얻을 수 있지만 유지보수 측면에서 어려움을 겪는다. 예를 들어 다중정의 함수가 5개가 논리적 결함이 생긴다면 사용자는 5개 함수의 코드를 수정해야 할 것이다. 5개의 함수가 전부 사용되지 않는 다면 불필요한 코드가 생긴 것이며 메모리의 낭비로 이어진다. 이와같은 단점을 보완하기 위해 제공되는 기능이 함수 템플릿 이다.
템플릿은 일종의 틀 이며 판화의 틀을 만들어 여러 장의 판화를 인쇄하는 것과 같다. 이때 인쇄하는 것이 소스코드인 것이다.
template <typename T>
반환형식 함수이름 (매개변수)
템플릿은 위와 같은 형식으로 " template <typename T> " 와 같이 템플릿 자료형의 이름을 정한 뒤 일반 함수의 정의와 같이 정의하여 사용하면 된다.
EX
// HelloNew_C+.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다. // #include "stdafx.h" #include<iostream> #include<cstdio> #include<string> template <typename T> // 사용할 템플릿 함수의 자료형 이름 T add(T a, T b) // 템플릿 함수 반환 자료형 T, 템플릿 함수 매개변수 자료형 T { return a + b; } int _tmain(int argc, _TCHAR* argv[]) { std::cout << add(3, 5) << std::endl; // int 형식 std::cout << add(3.5, 5.5) << std::endl; // double 형식 return 0; }
위와 같은 결과가 나오며 각 템플릿 함수가 호출 될 때 어떤 자료형으로 인식되는지 살펴보자
1. int 자료형을 매개변수로 전달했을 때
이와 같이 int 자료형의 매개변수와 반환값을 가지는 add함수가 Call 되어 Stack 메모리에 올려진 것을 확인 할 수 있다.
2. double 자료형을 매개변수로 전달했을 때
double 자료형의 메개변수와 반환값을 가지는 add함수가 Call 된 것을 볼 수 있다.
inline 함수란 ?
인라인 함수는 매크로의 장점 + 함수의 장점을 모아둔 함수이다. 예를 들어 함수 하나가 호출되면 호출되는 함수로 인해 생기는 오버헤드 ( 매개변수 복사, 스택 조정, 제어 이동 등등 ) 가 존재 할 것이다. 물론 함수가 매우 간단한 일을 수행하는 함수라고 해도 말이다. ex ) a + b
이와 같이 매우 간단한 일을 처리하는 동작의 반복을 줄이기 위해 해당 동작을 함수로 정의하여 함수를 사용한 다면 그로인해 생기는 오버헤드 문제가 있다. 이러한 단점을 해결 해 주는 것이 매크로이다. 매크로는 외형은 함수와 같지만 컴파일러는 매크로를 함수처럼 Call 하는 것이아니라 해당 매크로의 기술 된 내용을 소스코드에 똑같이 따라 친다고 보면 된다. 따라서 함수처럼 Call 되는 과정이 없어지며 소스코드에 사용자가 작성한 메크로의 동작이 기술된다.
// HelloNew_C+.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다. // #include "stdafx.h" #include<iostream> #include<cstdio> #include<string> int fuction_add(int a, int b){ return a + b; } int _tmain(int argc, _TCHAR* argv[]){ int nTotal = 0; nTotal = fuction_add(3, 4); printf("%d", nTotal); return 0; }
위의 코드를 Debug 모드에서 컴파일하여 실행 시켜 보자 아래와 같은 어셈블리 코드로 번역된다.
fuction_add 함수를 Call 하기 위해 매개 변수인 3, 4 를 스텍에 push 한 뒤 함수를 Call 하고 있다. 이제 프로그램의 흐름은 Call 된 함수로 넘어갈 것이다.
위의 자료는 fuction_add 함수로 넘어온 어셈블리 코드이다. 실제로 호출 스텍에 함수가 올라가 있으며 해당 함수는add 하는 동작을 수행 후 함수를 반환하기 위해 Stack 메모리 영역의 내용을 하나씩 pop 하는 과정을 거쳐 마지막 으로 함수가 반환 된다. 이제 최적화 모드를 사용하여 해당 코드를 컴파일해 보자
분명 fuction_add 함수를 작성하여 Call 하는 구문이 존재하지만 실제 동작을 보면 함수를 Call 하지 않으며 해당 함수의 매개변수로 전달 된 3 과 4를 더한 값 7을 바로 Stack 메모리에 Push 하였다. 따라서 fuction 함수를 분명 Call 하였지만 내부적으로는 3 과 4를 더하는 과정 없이 그냥 7 이라는 값을 printf 함수를 콜하며 해당 함수의 매개변수로 전달한다.
이와같은 이유는 컴파일러 최적화 옵션에 아래와 같이 기본적으로 인라인 함수 확장 옵션이 선택 되어있기 때문이다. 즉 컴파일러는 최적화 모드로 컴파일 할 시 함수를 분석하여 만약 인라인 함수로 변경해도 괜찮다고 판단시 해당 함수는 인라인 함수로 바꾸어 버린다.
'C++ 언어' 카테고리의 다른 글
생성자 함수와 소멸자 함수 (0) 2020.04.02 Class의 생성 과정 (0) 2020.03.31 참조자의 내부 동작 (0) 2020.03.27 참조형과 포인터 (0) 2020.03.26 C++ 메모리 동적할당 및 해제 ( new & delete ) (0) 2020.03.26