티스토리 뷰

객체 지향 프로그래밍을 향한 마지막 관문이다. reference는 object에 specific 한 개념은 아니지만, 종종 자주 쓰이기 때문에 알아두면 좋다.

// By pointer

void foo(int* num) {
	*num *= 2;
}

// By reference

void foo(int& num) {
	num *= 2;
}

어떤 변수의 값을 함수를 통해 변경하는 방법은 C를 이용한 포인터의 개념을 설명할 때 언급한 적이 있다. 바로 변수의 주소를 보내고, 그 주소를 역참조하여 변수의 값을 변경시키는 것이다. 이와 같이 포인터를 이용하여 주어진 변수의 값을 변경할 수도 있지만 reference를 이용하는 방법도 있다. 왜 두 가지 방법이 존재하는 걸까? 그리고 이들의 장단점은 뭘까?

 

포인터의 장점

 

1. 널포인터에 대한 유효성 검사

void foo(int* ptr) {
    if (ptr != nullptr) {
        // 포인터가 유효한 경우에만 동작 수행
        // ...
    } else {
        // 포인터가 널 포인터인 경우에 대한 처리
        // ...
    }
}

우리가 사용하려고 하는 포인터가 가리키고 있는 주소가 있는지 없는지 검사할 수 있다. 이를 통해 예기치 못한 오류를 사전에 방지할 수 있다.

 

2. 여러 변수에 대한 참조 전달 가능

포인터는 메모리 주소를 가리키기 때문에 여러 변수의 값을 한 번에 변경할 수 있는 장점이 있다.

 

포인터의 단점

 

1. 주소 연산자(&)와 역참조 연산자(*)의 빈번한 사용

포인터가 복잡하고 어렵게 느껴지는 이유의 대부분에 해당한다. 다소 헷갈리기 때문에 사용이 쉽지 않다.

 

2. 잘못된 메모리 주소 접근

포인터의 첫번째 장점이 반대로 단점이 될 수 있다. 유효성 검사를 하지 않을 시 예기치 못한 오류가 발생할 수 있다.

 

참조의 장점

 

1. 코드의 간결화

함수의 인자로 변수를 그냥 집어넣으면 된다. 해당 변수의 값을 참조하는 것이기 때문에 코드가 매우 간결하다.

 

2. 안정성

널값을 참조할 수 없다. 따라서 예기치 못한 오류가 발생할 일이 없다.

 

참조의 단점

 

1. 한 번에 하나의 변수 변경

한 인자로 한 변수만 전달할 수 있고, 포인터처럼 주소를 옮겨가며 값을 변경할 수 없다. 한 실행에 한번의 변수 변경만 가능하다.

 

2. 예기치 못한 변수 변경

참조된 값은 함수 내에서 아주 쉽게 변경될 수 있으므로 코드 작성에 주의가 필요하다.

 

참조 활용 예제

 

함수를 생성한다. 인자로 초기화된 두 실수와 초기화되지 않은 한 실수를 받는다. 초기화된 두 실수의 나눗셈 연산을 진행 후 결괏값을 초기화되지 않은 변수에 저장한다. 해당 값을 메인 함수에서 출력한다.

#include <iostream>
using namespace std;

void divide(double numerator, double denominator, double& ans) {
	ans = numerator / denominator;
}

int main() {

	double a = 10;
    double b = 2;
    double ans;
    
    divide(a, b, ans);
    cout << ans << endl;
    
    return 0;
}

출력은 5로 나오게 된다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함