본문 바로가기
[공부]/C++

[C++] 기본 정리 10 - C++ 함수(참조자, 디폴트 인수, 오버로딩)

by 개발꿈냥무 2024. 2. 22.

참조자 (reference)

  • & 연산자 : (주소 연산자 아님) 타입을 식별하기 위해 사용되는 식별자
  • 선언된 참조자는 대상 변수와 같은 메모리 위치를 참조하게 됨
  • 참조자를 이용해 연산을 수행하면, 참조 변수뿐 아니라 대상 변수도 같이 변경
  • 특정 변수의 실제 이름 대신 사용
  • 크기가 큰 구조체같은 데이터를 함수의 인수로 전달해야 할 경우에 사용
  • C++ 클래스를 설계할 때도 자주 사용

 

참조자 선언

int 변수이름; // 변수 선언

int& 참조자이름 = 변수이름; // 참조자 선언
int&는 int형 변수에 대한 참조를 의미

예시)
int x = 1;
int& y = x;

y++; //-> x, y의 데이터는 모두 2가 됨

 

참조자 선언할 때 주의할 사항

  1. 참조자의 타입은 대상 변수의 타입과 일치해야 함
  2. 참조자는 선언과 동시에 초기화되어야 함
  3. 한 번 초기화하면, 참조하는 대상을 변경할 수 없음

 

함수의 인수로서 전달

  • 함수가 참조자를 인수로 전달받으면, 참조자가 참조하고 있는 실제 변수의 값을 함수 내에서 조작 가능
  • 참조에 의한 전달(call by reference)는 참조자뿐만 아니라 포인터를 사용해도 같은 결과를 얻을 수 있으나, 구문 형태상의 차이만 있음

C++에서 함수 인수로 참조자(&) 사용하는 방법의 특징

  1. 함수 내에서 참조 연산자(*)를 사용하지 않아서, 함수 내부 코드가 직관적이고 깔끔해짐
  2. 함수의 호출이 값에 의한 전달(call by value)방법과 같은 형태가 되어, 코드 읽기가 쉽지 않음 -> 간단한 함수에서는 굳이 참조에 의한 전달을 하지 말고, 값에 의한 전달을 사용하면 good
void Swap( int& x, int& y )
{
	int temp = x;
	x = y;
	t = temp;
}

int num1 = 2, num2 = 4;
Swap( num1, num2 );
// -> num1 == 4, num2 == 2 로 변경됨

 

 

구조체의 참조

  • 구조체를 참조하는 방법은 변수 참조와 같음
  • 함수 내부에서 구조체를 직접 변경할 필요가 없을 땐, const 키워드를 사용하여 원본 구조체에 대한 변경을 허용하지 않는 것이 좋음
struct Book {
	string title;
	string author;
	int price;
};

void Display(const Book& bk) {
	cout << "제목 : " << bk.title << ", ";
	cout << "저자 : " << bk.author << ", ";
	cout << "가격 : " << bk.price << " 입니다.";
}

 

 


디폴트 인수 (default argument)

= 기본값이 미리 정의되어 있는 인수

 

함수를 호출할 때 인수를 전달하지 않으면, 함수는 자동으로 미리 정의되어 있는 디폴트 인수값을 사용함

 

 

디폴트 인수 설정 시 주의할 점

  1. 함수의 원형에만 지정 가능
  2. 가장 오른쪽부터 시작하여 순서대로만 지정 가능
  3. 가운데 인수들만 별도로 디폴트 인수를 지정할 수는 없음
void Display(int x, int y, char ch, int z = 4); -> 가능
void Display(int x, int y, char ch = 'a', int z = 4); -> 가능

void Display(int x, int y = 2, char ch, int z = 4); -> 오류
void Display(int x = 1, int y = 2, char ch, int z); -> 오류

 

 

디폴트 인수가 설정된 함수 호출

함수로 전달된 인수는 왼쪽부터 순서대로 매개변수 목록에 대입됨

즉, 디폴트 인수가 설정된 함수 호출 시 인수의 전달을 건너뛸 수 없음

void Display(int x, int y, char ch = 'a', int z = 4);

Display(1, 2); -> 가능 (Display(1, 2, 'a', 4)와 같음)
Display(3, 4, 'b'); -> 가능 (Display(3, 4, 'b', 4)와 같음)
Display(5, 6, 'c', 9); -> 가능 (Display(5, 6, 'c', 9)와 같음)
Display(7, 8, , 9); -> 오류 : 인수 전달은 건너뛸 수 없음

 

 

 


함수 오버로딩 (function overloading)

= 같은 이름의 함수중복하여 정의하는 것

(vs. 디폴트 인수 : 인수의 개수를 달리하여 같은 함수를 호출)

  • 여러 함수를 하나의 이름으로 연결해 줌
  • 같은 일을 처리하는 함수를, 매개변수의 형식을 조금씩 달리하여 하나의 이름으로 작성하게 해 줌
  • 매개변수의 타입뿐만 아니라, 개수를 달리해도 작성 가능
  • 객체 지향 프로그래밍의 특징 중, 다형성(polymorphism)의 구현

 

함수 시그니처 : 함수 오버로딩의 핵심

  • 함수의 원형에 명시되는 매개변수 리스트를 의미
  • 두 함수가 매개변수의 개수, 타입이 모두 같다면, 두 함수의 시그니처가 같다고 할 수 있음
  • 즉, 함수 오버로딩은 서로 다른 시그니처를 갖는 여러 함수를 같은 이름으로 정의하는 것!

 

C++ 컴파일러는 오버로딩된 함수가 호출되면, 그것과 같은 시그니처를 갖는 함수의 원형을 찾아 호출

오버로딩 함수의 "모호한 호출"을 허용하지 않으며, 오류 발생

1. void Display(const char* s, int n);
2. void Display(const char* s1, const char* s2);
3. void Display(int x, int y);
4. void Display(double x, double y);

// 호출 예시
Display("C++", 3); -> 1번 함수 호출
Display("C++", " Programming"); -> 2번 함수 호출
Display(3, 4); -> 3번 함수 호출
Display(4.2, 2.1); -> 4번 함수 호출

Display(4.2, 3); -> 3번,4번 모두 호출 가능 -> 컴파일 오류 발생!

 

 

 

 


참고)

코딩의 시작, TCP School

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com