C++/C++

8. 함수의 활용 ★

메카인 2023. 7. 12. 15:56

◆인라인 함수

●시간을 효율을 위해, 일반적인 함수의 호출 과정을 거치지 않고 호출된 자리에 코드를 넣는 방식이다.

  • 함수 선언 앞에 inlilne이라는 키워드를 붙인다.
  • 함수 정의 앞에 inline이라는 키워드를 붙인다.
  • 인라인 함수는 재귀 호출이 허용되지 않는다.
  • 매크로에 비해 인라인이 문법적 자유를 가지고 있어 인라인을 써야 한다. 
int a = 2;
cout<<SQUARE(a++);	// a++연산이 두번 되어 3*3이 아니라 4*4가 된다.

 

◆참조 변수

●주소를 나타내기 위한 & 기호를 통해 참조 변수를 만들 수 있다.

int home;
int & homeAddress = home;
  • 여기서는 &가 주소 연산자가 아니라, 데이터형 식별자의 일부로 사용된 것이다.
  • 참조를 선언할 때  참조 변수를 함께 초기화를 해주어야 한다.
  • 연결된 참조 변수는 다른 것과 연결될 수 없다. (const와 비슷하다.)
int & homeAddress1 = home;
int * const homeAddress2 = home; //본질적으로 같다. (homeAddress1 == *homeAddress2)

 

●참조는 주로 함수의 매개변수로 사용된다. 

  • 매개변수로 주면 값을 빠르게 전달이 가능하되, 메모리 위치를 다르게 할 수 없기 때문이다.

 

●포인터와의 차이점

  • 포인터를 이용하는 경우에는 함수가 p와 q를 사용할 때마다 내용 참조 연산자인 *를 사용해야 한다는 것이다.

 

▷▷▷▷▷참조 매개변수는 구조체나 클래스와 같이 덩치 큰 데이터를 다룰 때에나 유익하다.

 


◆lvalue란 무엇인가?

●참조가 가능한 데이터 객체이다.

●변수, 배열의 원소, 구조체의 멤버, 참조 또는 역참조 포인터는 lvalue이다.


●참조가 const로 선언되어 있으면, C++는 필요할 때 임시 변수를 생성한다. 기본적으로, 형식 매개변수가 const 참조로 되어 있는 함수는, 데이터형이 일치한지 않는 실제 매개변수를 전달받았을 때, 정보를 값으로 전달받는 전통적인 방식을 따른다. 즉 임시 변수를 사용하므로 원본 데이터를 변경하지 않는다.

 

●참조 매개변수를 상수 데이터에 대한 참조로 선언하는 이유

  • const를 사용하면, 실수로 데이터 변경을 일으키는 프로그래밍 에러를 막을 수 있다.
  • 함수 원형에 const를 사용하면, 함수가 const와 const가 아닌 실제 매개변수를 모두 처리할 수 있지만, 함수 원형에 const를 생략한 함수는 const가 아닌 데이터만 처리할 수 있다.
  • const 참조를 사용하면, 함수가 자신의 필요에 따라 임시 변수를 생성하여 사용할 수 있다.

 

●참조를 리턴하는 함수는 실제로 참조가 되는 변수에 대한 alias(별명) 파일이다.

 

●참조를 리턴할 때 주의할 점

▷함수가 종료할 때 수명이 함께 끝나는 메모리 위치에 대한 참조를 리턴하지 않도록 조심하는 것이다.

▷이 문제를 피하는 방법은, 함수에 매개변수로 전달된 참조를 리턴하는 것이다.

 

●const를 매개변수 혹은 lvalue로 사용하려면, 이 값이 변하지 않음을 보장해주기 위해 const로 선언된 변수에 대입해주어야 한다.

 

◆초기 포맷팅 상태 저장

ios_base::fmtflags initial;
initial = os.setf(ios_base::fixed); //초기 포멧팅 상태 저장.

os.precision(0);
os.setf(ios::showpoint);
os.precision(1);
os.width(5)

os.setf(initail); 					//초기 포멧팅 상태 복원

 

 

◆참조 매개변수를 쓰는 이유

  • 호출 함수에 있는 데이터 객체의 변경을 허용하기 위해
  • 전체 데이터 객체 대신에 참조를 전달하여 프로그램의 속도를 높이기 위해
  • ※이것은 단지 지침일 뿐이다.

●함수가 전달된 데이터를 변경하지 않고 사용만 하는 경우:

  • 데이터 객체가 기본 데이터형이나 작은 구조체라면 값으로 전달한다.
  • 데이터 객체가 배열이라면 포인터가 유일한 선택이므로 포인터를 사용한다. 포인터를 const를 지시하는 포인터로 만든다.
  • 데이터 객체가 덩치 큰 구조체라면 const 포인터나 const 참조를 사용하여 프로그램의 속도를 높인다. 이것은 구조체나 클래스 설계를 복사하는 데 드는 시간과 공간을 절약한다.
  • 데이터 객체가 클래스 객체라면 const 참조를 사용한다. 클래스 설계 자체가 흔히 참조를 사용할 것을 요구한다. 이것이 C++에 const 기능을 추가한 주된 이유이기도 하다. 클래스 객체 매개변수의 전달은 참조로 전달하는 것이 표준이다.

 

●함수가 호출 매개변수의 데이터를 변경하는 경우 (매개변수의 deep copy)

  • 데이터 객체가 기본 데이터형이면 포인터를 사용한다. 
  • 데이터 객체가 배열이면 유일한 선택은 포인터를 사용하는 것이다.
  • 데이터 객체가 구조체이면 참조 또는 포인터를 사용한다.
  • 데이터 객체가 클래스 객체이면 참조를 사용한다.

 

 

◆디폴트 매개변수

  • 함수에 들어가는 매개변수의 기본값을 지정해준다.
  • 매개변수 리스트를 사용할 때 디폴트 매개변수가 있는 매개변수를 오른쪽에 첨가해야한다.

 

◆이름 장식(Name Decoration)

  • 컴파일러는 자신의 사용을 위해 알아보기 어려운 내부형식으로 함수이름을 바꾼다.

 

◆함수 템플릿

  • 임의 데이터형으로 함수를 정의하는 것을 허용한다.
template <class Any>			//Any 대신 typename을 작성해도 된다.
void Swap(Any &a, Any &b){

	Any temp;
    temp = a;
    a=b;
    b=temp;
   }
  • 장점 : 여러 개의 함수 정의를 더 간단하고 더 신뢰성있게 생성한다.

 

◆템플릿의 오버로딩

●3세대 특수화(ISO/ANSI C++표준)

  • 함수 이름이 하나 주어지면, 사용자는 템플릿이 아닌 함수(일반 함수), 템플릿 함수, 명시적 특수화 템플릿 함수를 가질 수 있다. 또한 이 모든 것들의 오버로딩 버전도 가질 수 있다.
  • 명시적 특수화를 하기 위한 원형과 정의 앞에 template <>가 와야 한다. 그리고 그 특수형의 이름을 서술해야 한다.
  • 특수화는 템플릿을 무시하고, 템플릿이 아닌 함수는 특수화와 템플릿 둘 다를 무시한다.
//job형을 위한 명시적 특수화
template <> void Swap<job>(job &,job &)

 

◆템플릿의 구체화(instantiation) 그리고 암시적 구체화(implicit instantiation)

  • 모든 자료형의 템플릿이 구체화 되지는 않는다. 코드상에서 int형으로 Swap()을 사용하였을 경우 int형을 사용하는 Swap()을 구체화 하게 만든다.
  • 이러한 방식을 암시적 구체화(implicit instantiation)라고 한다.
  • 암시적 구체화, 명시적 구체화, 명시적 특수화를 모두 특수화(specialization)라고 한다.
  • 모두 구체적인 데이터형을 사용하는 함수 정의를 나타낸다는 것이다.
template <> void Swap<job>(job &, job &)		//job을 명시적 특수화

template void Swap<char>(char &, char &)		//char을 위한 명시적 구체화

short a.b;
Swap(a,b); 				//short를 위한 암시적 템플릿 구체화

job c,d;
Swap(c,d); 				//job을 위한 명시적 특수화를 사용한다.

char e,f;
Swap(e,f); 				//char를 위한 명시적 템플릿 구체화를 사용한다.

 

◆템플릿의 정확한 대응과 최선의 대응

 

●정확한 대응을 위해 허용되는 사소한 변환

변환 전 실제 매개변수 변환 후 형식 매개변수
Type Type &
Type & Type
Type [] * Type
Type (argument-list) Type (*) (argument-list)
Type const Type
Type volatile Type
Type * const Type *
Type * volatile Type *