728x90
황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!
https://search.shopping.naver.com/book/catalog/32436115747
함수 중복
- C++에서는 C와 달리 같은 이름의 함수를 여러 개 만들 수 있으며 이것을 함수 중복(function overloading)이라고 부른다.
- OOP 특징인 다형성의 한 예시로서 전역 함수와 멤버 함수에 모두 적용
- 기본 클래스와 파생 클래스 사이에도 허용
중복 함수 조건
- 중복된 함수들의 이름이 동일하여야 한다.
- 중복된 함수들은 매개 변수 타입이나 매개 변수의 개수가 달라야 한다.
- 함수 중복에 리턴 타입은 고려되지 않는다.
- 아래는 성공 예시와 실패 예시이다.
// 성공사례
int sum(int a, int b, int c) {
return a + b + c;
}
double sum(double a, double b) {
return a + b;
}
int sum(int a, int b) {
return a + b;
}
int main() {
cout << sum(2, 5, 33);
cout << sum(12.5, 33.7);
cout << sum(2, 6);
}
// 실패 사례
int sum(int a, int b) {
return a + b;
}
double sum(int a, int b) {
return (double)(a+b);
}
int main() {
cout << sum(2, 5); // 어떤 sum() 함수인지 컴파일러가 구분할 수 없음.
}
함수 중복의 편리함
- 함수 중복의 경우 작성의 편리함과 이름을 구분지어 기억할 필요가 없어 함수를 잘못 호출하는 실수를 줄일 수 있다.
- 또한, C++ 컴파일러는 함수 중복이 성공적인지 판별하고, 중복된 함수의 호출이 옳은 지 확인한다.
- 함수 중복은 컴파일 시에 이루어지기 때문에, 함수 중복으로 인한 실행 시간 저하는 없다.
생성자 함수 중복
- 이미 앞에서 봤듯이 Circle 클래스에 2개의 생성자를 중복 작성하였다.
Circle();
Circle(int r);
- 객체 생성 시 매개 변수를 통해 다양한 형태로 초깃값을 전달하기 위해 생성자 함수를 중복 선언
- 아래는 string 클래스의 다양한 생성자 예시와 생성하는 예
class string {
....
public:
string(); // 빈 문자열을 가진 스트링 객체 생성
string(char* s); // \0로 끝나는 c-스트링 s를 스트링 객체로 생성
string(string& str); // str을 복사한 새로운 스트링 객체 생성
};
// ======================
string str;
string address("우리집");
string copyAddress(Address);
소멸자 함수 중복
- 소멸자는 매개 변수를 가지지 않기 때문에 한 클래스에 오직 하나만 존재한다.
- 즉, 소멸자 함수의 중복은 근본적으로 불가능하다.
디폴트 매개 변수
함수가 호출될 때 매개 변수에 값이 넘어오지 않는다면, 미리 정해진 디폴트 값을 받도록 선언된 매개 변수를 디폴트 매개 변수 혹은 기본 매개 변수라고 부른다.
선언
// 매개 변수 = 디폴트 값 형태로 선언
void star(int a=5); // a의 디폴트 값 5
제약 조건
- 디폴트 매개 변수는 모두 끝 쪽에 몰려 선언되어야 한다.
- 즉, 보통 매개 변수 앞에 선언 될 수 없음
void calc(int a, int b=5, int c, int d=0); // 컴파일 오류
void sum(int a=0; int b, int c); // 컴파일 오류
// 수정
void calc(int a, int b=5, int c=0, int d=0);
void sum(int a=0;, int b=0, int c=0);
값을 정하는 규칙
- 디폴트 매개 변수를 가지고 있는 함수의 호출문을 컴파일 할 때, 컴파일러는 함수 호출문에 나열된 실인자 값들을 앞에서부터 순서대로 함수의 매개 변수에 전달하고, 나머지는 디폴트 값으로 전달한다.
- 디폴트 매개 변수만 가진 경우와 보통 매개 변수도 가진 경우를 살펴보자.
포인터 변수의 디폴트 값
- 포인터 변수를 디폴트 매개 변수로 선언할 때에는 아래와 같이 디폴트 값을 줄 수 있다.
void f(int *p=NULL);
void g(int x[]=NULL);
void h(const char *s = "Hello");
함수 중복 간소화
- 디폴트 매개 변수의 최대 장점은 함수 중복을 간소화 할 수 있다는 점이다.
class Circle {
...
public:
Circle() { radius = 1; }
Circle(int r) { radius = r; }
};
class Circle {
...
public:
Circle(int r=1) { radius = r; }
};
- 다만, 디폴트 매개 변수를 가진 함수는 같은 이름의 중복 함수들과 함께 선언될 수 없다.
함수 중복의 모호성
- 중복 조건을 갖추었다 하더라도 중복된 함수에 대한 호출이 모호(ambiguous)해지는 경우가 발생한다.
- 함수 중복의 모호성이 발생하는 경우는 아래 3가지가 있다.
- 형 변환으로 인한 모호성
- 참조 매개 변수로 인한 모호성
- 디폴트 매개 변수로 인한 모호성
형 변환으로 인한 모호성
- 일반적으로 함수의 매개 변수 타입과 호출 문의 실인자 타입이 일치하지 않는 경우, 컴파일러는 보이지 않게 형 변환(type conversion)을 시도
double square(double a); // double 타입의 매개 변수를 가진 함수
square(3); // int 타입의 매개 변수 전달. 컴파일 오류 발생하지 않음!!
- 컴파일러는 아래와 같이 작은 타입을 큰 타입으로 자동 형 변환한다.
char -> int -> long -> float -> double
다만, double과 float 타입을 인자로 받는 함수가 2개 있을 때, int 형 인자를 전달 시 어느 타입으로 형변환을 할지 모호하기 때문에 컴파일 오류가 발생한다.
참조 매개 변수로 인한 모호성
int add(int a, int b);
int add(int a, int &b);
int s=10, t=20;
add(s, t); // 컴파일 오류. 함수 호출의 모호성
디폴트 매개 변수로 인한 모호성
void msg(int id){};
void msg(int id, string s="");
주의할 점!!
- 배열의 이름은 포인터이기 때문에, 아래 두 함수는 같은 함수로서 공존할 수 없다.
void f(int a[]);
void f(int* a);
728x90
'Programming Language > C++' 카테고리의 다른 글
[C++] 프렌드 (1) | 2023.12.05 |
---|---|
[C++] static 멤버 (0) | 2023.12.05 |
[C++] 복사 생성자 (1) | 2023.12.04 |
[C++] 참조에 의한 호출, call by reference (0) | 2023.12.04 |
[C++] 함수와 참조 (0) | 2023.12.03 |