[C++] 디폴트 매개변수, 매개변수의 default 값

728x90
반응형

함수 매개변수의 default 값 지정

C++에서는 함수 매개변수에 default 값을 지정할 수 있다.

#include <iostream>

int add(int n1 = 10, int n2 = 20, int n3 = 30)
{
    return n1 + n2 + n3;
}

int main()
{
    std::cout << add() << std::endl;

    return 0;
}

3번째 줄 add함수의 매개변수 n1, n2, n3에 default 값 10, 20, 30이 지정돼 있다. 이와 같이 함수의 매개변수에 default 값을 지정할 수 있다. add함수를 호출 할 때 별도의 값을 매개변수에 전달하지 않으면 add함수의 매개변수 n1, n2, n3는 지정된 default 값으로 초기화된다. 따라서 위 코드의 실행 결과는 아래와 같다.

실행결과
60

매개변수의 default 값 지정은 오른쪽에서 왼쪽으로 지정해야 한다.

함수 매개변수에 default 값을 지정할 때 반드시 오른쪽에서 왼쪽 순서로 지정해야 한다.

#include <iostream>

int add(int n1, int n2, int n3 = 30)
{
    return n1 + n2 + n3;
}

int main()
{
    std::cout << add(1, 2) << std::endl;

    return 0;
}

함수를 호출 할 때 전달 인자가 전달되는 순서를 생각해보자. 위 코드와 같이 add함수를 호출하고 전달 인자로 1과 2를 전달하면 1은 n1에 전달되고, 2는 n2에 전달된다. n3에는 default 값으로 30이 지정되어 있기 때문에 실행 결과는 다음과 같을 것이다.

실행결과
33

아래와 같이 가장 왼쪽의 n1에 default 값을 지정하고 컴파일 해보면 에러가 발생하는 것을 확인 할 수 있다.

#include <iostream>

int add(int n1 = 10, int n2, int n3)
{
    return n1 + n2 + n3;
}

int main()
{
    std::cout << add(1, 2) << std::endl;

    return 0;
}

add함수를 호출하면서 1과 2를 전달하면 1은 n1에 전달되고 2는 n2에 전달된다. n3에는 어떠한 값도 지정되지 않았기 때문에 컴파일 에러가 발생한다.

**매개변수에 default 값을 지정할 때는 반드시 오른쪽에서 왼쪽 순서로 지정을 해야 한다.

default 값 표현은 함수의 선언 부분에만 표시해야 한다.

아래 코드는 main()함수 위에 add함수가 선언되어 있고 n3에 default 값이 지정되어 있기 때문에 정상적으로 컴파일 된다.

#include <iostream>

int add(int n1, int n2, int n3 = 30)
{
    return n1 + n2 + n3;
}

int main()
{
    std::cout << add(1, 2) << std::endl;

    return 0;
}

이와 같은 형태가 아니라 함수 원형을 별도로 선언하는 경우 매개변수의 default 값은 함수 원형 선언 할 때 같이 지정해 줘야 한다.

#include <iostream>

int add(int n1, int n2, int n3 = 30);

int main()
{
    std::cout << add(1, 2) << std::endl;

    return 0;
}

int add(int n1, int n2, int n3)
{
    return n1 + n2 + n3;
}

함수 원형이 .h파일에 선언된 경우도 동일하고, class에 선언된 경우도 동일하게 적용된다.

default 값 지정과 함수 오버로딩(Function Overloading)

#include <iostream>

void print(int a)
{
    std::cout << a << std::endl;
}

void print(int a, int b = 10)
{
    std::cout << a <<", "<< b << std::endl;
}

int main()
{
    print(10);
}

위 코드와 같은 경우 함수 오버로딩이 적용되지만, 8번째 줄에 선언된 void print(int a, int b = 10)함수에서 default value를 지정하고 있기 때문에 default 매개변수를 사용한 함수*와 *오버로딩된 함수 사이에 모호성이 발생할 수 있다.
16번째 라인에서 print(10) 함수를 호출하게 되면 컴파일러는 아래 두 가지 가능성을 두고 혼란을 겪게 되어 컴파일 에러를 발생한다.

  1. void print(int a)함수 호출
  2. void print(int a, int b = 10) 함수 호출
    16번째 라인에서 print(10) 함수 호출은 두 가지 경우 모두 만족하는 경우기 때문에 모호성이 발생한다.

default 값은 반드시 상수여야 한다.

매개변수의 default 값을 지정 할 때는 반드시 상수로 지정해야 한다. 함수의 호출 결과를 default 값으로 사용 할 수 없다.

함수 포인터 사용 시 매개변수의 default 값

#include <iostream>

void Func(int a = 10)
{
    std:;cout << a << std::endl;
}

int main()
{
    void(*FuncPtr)(int) = Func;
    FuncPtr(20);
}

10번째 줄(void(*FuncPtr)(int) = Func)에서 Func 함수를 포인터로 지정할 때 Func매개변수의 default 값은 사라진다. 따라서 반드시 매개변수에 어떠한 값을 전달해 줘야 한다.

Class 상속에서 매개변수의 default 값

[[상속(Inheritance)]]
[[Class]]

Class 상속에서 기본 클래스의 default 매개변수 값은 유도 클래스에서 상속되지 않는다. 따라서 기본 클래스의 디폴트 매개변수를 변경해도 유도 클래스는 영향을 받지 않는다.

class Base {
public:
    virtual void Print(int x = 10) {
        std::cout << "Base: " << x << std::endl;
    }
};

class Derived : public Base {
public:
    void Print(int x = 20) override {
        std::cout << "Derived: " << x << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived;
    basePtr->Print();  // 출력: "Derived: 10" -> Base 클래스의 디폴트 값 사용
}
728x90
반응형