Language/C++

[C++] CH5 함수와 참조, 복사 (1)

nowkoes 2023. 2. 28. 15:50

함수와 인자 전달 방식

Call by Value

  • 정의: 호출하는 코드에서 넘겨주는 실인자 값이 함수의 매개 변수에 복사되어 전달되는 방식
  • 특징
    • 함수 내에서 실인자를 손상시킬 수 없음
    • 실인자의 크기가 크면 오버헤드가 발생하여 복사하는 시간이 길어짐
    • 생성자는 실행되지 않고, 소멸자만 실행됨 (생성자와 소멸자 비대칭 문제)
     

두 매개변수를 바꾸는 swap 함수를 값에 의한 호출로 동작하는 과정을 시각화한 그림

 

Call by Address

  • 정의: 주소를 직접 포인터 타입의 매개 변수에 전달하는 방식
  • 특징
    • 의도적으로 함수 내에서 실인자의 값을 변경시킬 때 사용
    • 원본 객체를 복사하는 시간 소모가 없음
    • 생성자와 소멸자의 비대칭 문제가 없다
     

두 매개변수를 바꾸는 swap 함수를 주소에 의한 호출로 동작하는 과정을 시각화한 그림


함수 호출 시 객체 전달

 다음 예제에 있는 각각의 출력문 cout에서 waffle의 radius 값을 생각해보자.

// 예제 5-1
#include <iostream>
using namespace std;

class Circle
{
    int radius;

public:
    Circle() 
    { 
        radius = 1;
        cout << "생성자 실행 radius = " << radius << endl; 
    }

    Circle(int r) 
    { 
        radius = r;
        cout << "생성자 실행 radius = " << radius << endl; 
    }

    ~Circle() 
    { 
        cout << "소멸자 실행 radius = " << radius << endl;
    }

    double getArea()
    { 
        return 3.14 * radius * radius; 
    }

    int getRadius() 
    { 
        return radius;
    }
    void setRadius(int radius)
    { 
        this->radius = radius;
    }
};

void increase(Circle c)
{
    int r = c.getRadius();
    c.setRadius(r + 1);

    cout << "increase 함수에서 radius: " << c.getRadius() << endl;
}

int main()
{
    Circle waffle(30);
    increase(waffle);

    cout << "waffle의 radius: " << waffle.getRadius() << endl;
}

 

Circle waffle(30);

 waffle 객체를 생성함과 동시에 아래의 코드가 실행된다.

 

Circle(int r) 
{ 
    radius = r;
    cout << "생성자 실행 radius = " << radius << endl; 
}

 따라서 먼저 "생성자 실행 radius = 30"이라는 문구가 출력될 것이다.

 

increase(waffle);

 이제 이 객체를 함수의 인자로서 전달해보자.

 

void increase(Circle c)
{
    int r = c.getRadius();
    c.setRadius(r + 1);

    cout << "increase 함수에서 radius: " << c.getRadius() << endl;
}

 해당 함수의 Circle c는 기존의 waffle의 복사본으로서 값에 의한 호출로 생성된 객체다. 따라서 c의 생성자를 초기화하는 과정은 생략되고, 복사본의 반지름 radius값에 1이 더해진 체 "increase 함수에서 radius : 31"이라는 문구가 출력될 것이다. 그리고 함수가 종료됨에 따라 c가 소멸하고, 소멸자 함수가 실행되어 "소멸자 실행 radius = 31"이라는 문구가 출력된다.

 

cout << "waffle의 radius: " << waffle.getRadius() << endl;

 그리고 마지막으로 wafffle의 radius는 실인자가 바뀐 것이 없기 때문에 "waffle의 radius : 30"이 출력될 것이고, waffle의 소멸자 함수가 호출되어 "소멸자 실행 radius = 30"이라는 문구가 출력된다.

 

 만약 increase() 함수를 통해 실인자 값을 바꾸고 싶으면 매개 변수 앞에 & 연산자 혹은 * 연산자를 이용하면 된다.

 


 

 

반응형