객체 지향 프로그래밍을 향한 마지막 관문이다. 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로 나오게 된다.
'Computer Science and Engineering > OOP (Object Oriented Programming)' 카테고리의 다른 글
[OOP, C++] Class 기초 - 선언, 초기화, 사용 (0) | 2023.05.22 |
---|---|
[Syntax, C++] struct, enum, union을 활용하여 계산기 구현하기 (0) | 2023.05.02 |
[Syntax, C++] struct를 활용하여 다각형의 둘레의 길이 구하기 (0) | 2023.04.27 |
[Syntax, C++] struct, enum class를 활용하여 날짜(D - day) 계산하기 (0) | 2023.04.27 |
[Syntax, C++] Array에서의 Pointer (0) | 2023.03.21 |