Brise
[C++ 기본] 6. Function 본문
// C++함수의 특징 1. 디폴트 파라미터
// 주의 사항 1. 반드시 마지막 인자(오른쪽) 부터 차례대로
// 지정해야 한다.
// 주의 사항 2. 함수를 선언과 구현으로 분리할 경우
// 선언부에만 표기한다. (28 page 아래)
void foo(int a = 0, int b, int c = 0); // error
void foo(int a = 0, int b = 0 , int c = 0);
int main()
{
foo(1, 2, 3);
// foo(1, 2);
//foo(1);
//foo();
}
void foo(int a/* = 0*/, int b /*= 0*/, int c/* = 0 */)
{
}
C++은 멀티 패러다임 언어이기 때문에 OOP 적인 특징을 구현하고 있다. 때문에 함수에 대하여 default parameter를 지원한다. 인자를 생략하는 경우 기본값으로 입력되기 때문에 default parameter는 오른쪽에 지정되어야 한다.
#include <cstdio>
// 6_함수2
// C++ 함수의 특징 2. 함수 오버로딩
// 인자의 갯수가 다르거나 인자의 타입이 다르면 동일한 이름의
// 함수를 2개이상 만들수 있다.
//#define SQUARE(x) ((x)*(x))
//SQUARE(++n);
int square(int a)
{
return a * a;
}
double square(double a)
{
return a * a;
}
int main()
{
square(3);
square(3.4);
printf("%p\n", &square); // error
printf("%p\n", (int(*)(int)) &square); // ok
}
// ok
void f1(int);
void f1(double);
// error. 반환타입만 다른 경우 오버로딩 안됨.
void f2(int);
int f2(int);
// ok
void f3(int a);
void f3(int a, int b);
// error. 디폴트 값에 주의!
void f4(int a);
void f4(int a, int b = 0);
f4(5);
overloading을 사용하여 함수의 같은 이름의 함수, 같은 인자갯수의 함수에 인자 타입을 다르게 하여 함수의 입력에 따라 다른 함수로 접근할 수 있도록 할 수 있다.
같은 입력에 대하여 다른 output을 가지는 경우 매핑할 수 없으며, default parameter와 혼용시 결정이 어려운 경우가 있을 수 있으므로, 컴파일러 단게에서 오류를 발생시킨다.
// C++ 함수 특징 3. inline .. 32page
// 인라인 함수 : 호출이 아니라 기계어 코드를 치환해 달라는의미
// 장점 : 빠르다.
// 단점 : 여러번 치환되면 목적코드(실행파일 크기)가 커질수 있다
int add1(int a, int b) { return a + b; }
inline int add2(int a, int b) { return a + b; }
constexpr int add3(int a, int b) { return a + b; }
int main()
{
int n1 = add1(1, 2); // 호출
int n2 = add2(1, 2); // 치환
int n3 = add3(1, 2); // 컴파일 시간에 실행
int arr[add3(1, 2)];
arr[0] = 10;
}
// cl 6_함수3.cpp => 실행파일 생성
// cl 6_함수3.cpp /FAs => 6_함수3.asm 생성
// cl 6_함수3.cpp /FAs /Ob1
// /Ob1 : 인라인 치환을 적용해 달라.
// /FAs : 현재 C++ 소스의 어셈소스을 만들어달라
// /O2 : 속도를 위한 최적화 옵션
// notepad 6_함수3.asm
실행시간 최적화를 위하여 inline함수, constexpr함수를 사용할 수 있다. inline의 경우 함수를 실행하나, 최적화 하여 실행하는 것이고, constexpr는 컴파일러가 함수를 실행하여 결과를 반영한다.
// 6_함수4
// C++ 함수의 특징 4. 함수 템플릿
/*
int square(int a)
{
return a * a;
}
double square(double a)
{
return a * a;
}
*/
/*
#define MAKE_SQUARE(T) T square(T a) { return a* a;}
MAKE_SQUARE(int)
MAKE_SQUARE(double)
*/
// 전처리기가 아닌 컴파일러에 의한 코드 생성
// 컴파일러에게 함수가 아닌 함수를 만드는 틀을 알려준다.
template<typename T>
T square(T a)
{
return a * a;
}
int main()
{
square<int>(3); // int square(int)함수 생성후. 호출
square<double>(3.4); // double square(double)
// 타입을 전달하지 않으면 함수 인자를 보고 타입을 결정한다
square(3); //square<int>(3)
square(3.4);
printf("%p\n", &square); // error. square는 함수가 아니다
// 함수의 틀(template) 이다
printf("%p\n", &square<int>); // square<int>가 함수이름
}
// 33 page
함수 overloading을 수행하기 위해서는 각 타입별로 함수를 코딩해주어야 한다. 이러한 불편함을 해소하기 위해서 template를 사용할 수 있다. template 선언 시 template
// 6_함수5
// C++ 함수 특징 5. 함수 삭제. C++11에서 추가된 기능
// 35 page
int add(int a, int b)
{
return a + b;
}
// 36 page 아래 표
// 함수를 제공하지 않으면 : 인자의 암시적 변환에 의해서
// 동일이름의 다른함수 호출 가능
// 함수를 선언만 제공 : 사용했을때 link 에러 발생
// 함수를 삭제 할때 : 사용했을때 compile 에러 발생
//double add(double a, double b); // 핵심. 선언만 제공
double add(double a, double b) = delete; // C++11의 함수삭제
// 문법
int main()
{
add(1, 2);
add(2.3, 3.2); // compile error. 삭제된 함수 사용
}
overloading을 통하여 다른 타입에 대하여 함수 진입을 지정할 수 있다면, C++11에서 추가된 기능을 이용하여 특정 타입으로 함수를 호출하는 경우 함수 호출에 대하여 오류를 호출할 수도 있다.
#include <iostream>
/*
// overloading resolution : 함수 찾는 순서
void foo(int n) { std::cout << "int" << endl; }
void foo(short n) { std::cout << "short" << endl; }
//void foo(float n) { std::cout << "float" << endl; }
void foo(double n) { std::cout << "double" << endl; }
void foo(...) { std::cout << "..." << endl; }
//template<typename T>
//void foo(T n) { std::cout << "T" << endl; }
int main()
{
float f = 3.4f;
foo(f); // 1. exactly matching - float
// 2. template 사용해서 float 버전 생성 - T
// 3. promotion (데이타 손실이 없는 변환)
// - double
// 4. standard conversion(데이타 손실이 있어도
// float -> int 변환 가능 - int
// 5. 마지막 선택이 가변인자
}
*/
void goo(int, int) {} // 1
void goo(short, short) = delete; // 2
int main()
{
goo(1.3, 2.3); // 1을 선택할지 2를 선택할지 모른다는 에러
}
진입 가능한 함수가 여러개인 경우 순서에 따라 어떤 함수로 실행할지 정하게 된다.
- exactly matching - float
- template 사용해서 float 버전 생성 - T
- promotion (데이타 손실이 없는 변환)
- double - standard conversion(데이타 손실이 있어도
float -> int 변환 가능 - int - 마지막 선택이 가변인자
// 6_함수7
// C++함수 특징6. 후위 반환 타입 37 page
// suffix return type( trailing return type)
//int square(int a)
auto square(int a) -> int // C++11 부터 나온 새로운 함수 모양
{
return a * a;
}
int main()
{
square(3);
}
함수 선언 시 반환 타입에 대해서도 auto를 사용할 수 있다.
'프로그램 > C,C++' 카테고리의 다른 글
[C++ 기본] 9. 제어문 (0) | 2022.01.29 |
---|---|
[C++ 기본] 8. 반복문 (0) | 2022.01.29 |
[C++ 기본] 7. template function (0) | 2022.01.16 |
[C++ 기본] 5. constexpr (0) | 2022.01.15 |
[C++ 기본] 4. Variable (0) | 2022.01.14 |
[C++ 기본] 3. 입출력 (0) | 2022.01.14 |
[C++기본] 2. namespace (0) | 2022.01.14 |