[내일배움캠프/C++] 오버로딩, 템플릿

김세희·2025년 5월 30일

✍️Today I Learned

  1. 함수 오버로딩
  2. 템플릿

함수 오버로딩

같은 이름으로 다른 기능을 수행하는 함수를 만들 때 사용한다. 오버로딩을 사용하려면 호출되는 함수가 분명해야 한다.
C++에서 함수 이름이 같아도 매개변수의 타입이나 개수가 다르면 다른 함수로 구분한다.

❗오버로딩 실패하는 경우

  1. 타입 변환이 가능한 매개변수로 인해 두 개 이상의 오버로딩된 함수가 호출 후보가 되는 경우
  2. 디폴트 매개변수로 인해 함수 호출 형태가 중복되는 경우
  3. 매개변수 타입이 포인터와 배열로 다른 경우
    : 매개변수로 배열이 들어갈 때 시작 주소가 들어가기 때문에 포인터와 구분되지 않음
  4. 함수의 반환 타입만 다른 경우

함수 오버로딩 순서

오버로딩된 함수가 선택되는 순서

  1. 정확한 매개변수 타입 일치
  2. 타입 승격 변환
    : 값이 손실되지 않는 방향으로 변환하는 것을 승격이라고 한다.
  3. 표준 타입 변환
    : 승격보다 더 광범위하고 값 손실이 발생하는 경우도 있다.
  4. 사용자 정의 타입 변환
    : 클래스 타입의 변환 함수나 생성자 등을 통해 이뤄지는 변환

템플릿

타입에 상관없이 일반화된 코드를 작성하기 위한 문법
template <typename T>: 어떤 타입이 올지 모르나 그 타입을 T로 부르겠다는 의미이다.
-> T add(T a, T b): int, double, float, short 뭐든 더하는 함수. 하지만 같은 typename에는 같은 타입이 들어간다.

// 목적: 클래스 템플릿으로 배열을 일반화하여 원소 추가 및 삭제 기능 구현하기
#include <iostream>
using namespace std;

template <typename T>
class Array {
    T data[100];
    int size;
public:
    Array() : size(0) {}

    void add(const T& element) {
        if(size < 100)
            data[size++] = element;
    }

    void remove() {
        if(size > 0)
            size--;
    }

    void print() {
        for(int i = 0; i < size; i++)
            cout << data[i] << " ";
        cout << endl;
    }
};

int main() {
    Array<int> arr; // 정수형 배열 생성
    arr.add(10);
    arr.add(20);
    arr.add(30);
    arr.print();

    arr.remove();
    arr.print();
    return 0;
}

// 출력결과:
// 10 20 30
// 10 20

🤔 템플릿과 별개로 위 코드에서 궁금점
arr.add(10); 처럼 입력에 상수가 들어갈 수 있는 이유
add(const T& element)<- 상수 참조이기 때문. const가 없었으면 rvalue를 받을 수 없다.

상수 참조(const reference)

  1. 값을 바꿀 수 없는 참조(읽기 전용)이다.
  2. 임시 값(rvalue)도 참조할 수 있다.

🎯 왜 const T&는 rvalue를 받을 수 있을까?
예를 들어, arr.add(10);을 보면:

  1. 10은 rvalue로 메모리에 이름이 없는 임시 값이다.

  2. add(const T& element)는 상수 참조이므로, C++ 표준에 따라 rvalue도 받을 수 있다.

  3. 컴파일러는 내부적으로 10을 임시 변수처럼 메모리에 저장한 뒤, 그 주소를 const T&로 전달한다.

    • 임시 객체의 수명은 함수가 끝날 때까지 유지된다.
  4. add() 안에서 data[size++] = element;가 실행되면서 element의 값을 복사하게 된다.

0개의 댓글