728x90

황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!

https://search.shopping.naver.com/book/catalog/32436115747

 

C++ Programming : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

함수 중복

  • 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가지가 있다.
    1. 형 변환으로 인한 모호성
    2. 참조 매개 변수로 인한 모호성
    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