상세 컨텐츠

본문 제목

C++ Call By Reference

C++

by devTak 2021. 3. 2. 10:57

본문

반응형

C++ Pointer

C++ 에서의 Pointer("*") 는 메모리 값을 저장하는 변수로 볼 수 있다.

int main() {
    int num = 10;
    int* ptrNum = #
}
 
int main() {
    int num = 10;
    int* point_num1 = &num1;
    int** double_point_num1 = &point_num1;
    int*** triple_point_num1 = &double_point_num1;
    int**** quadruple_point_num1 = &triple_point_num1;
}

타입과 변수 사이에 "*" 를 작성하면 메모리 주소 값을 할당 할 수 있는 변수로 선언하게 된다.

위에 작성한 코드에서는 각 포인터 변수들은 각각의 주소 값을 가지고 있지만

중첩된 포인터 변수에 역포인터를 추가해서 찍어보면 결국 10의 주소 값을 가지고 있게 된다.

따라서, 아래와 같은 코드를 작성하면 값이 변경되는 걸 확인할 수 있다.

 

int main() {
    int num = 10;
    int* point_num1 = #
    int** double_point_num = &point_num;
    int*** triple_point_num = &double_point_num;
    int**** quadruple_point_num = &triple_point_num;
 
    ****quadruple_point_num  = 100;
 
    // num: 100 출력
    cout << "num: " << num << "\n";
    return 0;
}

일반적으로 자바스크립트에서 primitive data type( - boolean, null, undefined, Number, String, Symbol - ) 은 immutable value(메모리영역에서의 변경불가) 이다. 즉, immutable value 인 타입들은 shallow copy 가 불가능 하다.

 

하지만, 위처럼 C++ 에서는 포인터를 통해 shallow copy , 즉 메모리 참조 변수를 만들어서 mutable value 가 가능하도록 할 수 있다.

 

php 에서는 오히려 primitive data type 에 대한 개념이 없기 때문에 mutable 하게 처리된다.

 

(int) $test = 1;
(int) $test2 = &$test;
$test2 = 3;
 
// 3
echo $test;

Call By Reference / Call by Value

 

Call by value 는 인자로 받은 값을 복사(Deep Copy)하여 처리한다.

Call by reference 는 인자로 받은 값의 주소를 참조하여 직접 값에 영향을 준다.

 

void callByValueFunc(int param) {
    // main 에서의 value 주소 값 이랑 서로 다름.
    cout << "callByValueAddress:" << &param << "\n";
    param = 10;
}
 
void callByReferenceFunc(int *refer) {
    // main 에서의 refer 주소 값 이랑 서로 같음.
    cout << "callByReferenceAddress:" << refer << "\n";
    *refer = 10;
}
 
int main {
    int value = 0;
    int refer = 0;
    cout << "valueAddress:" << &value << "\n";
    callByValueFunc(value);
    cout << "referenceAddress:" << &refer << "\n";
    callByReferenceFunc(&refer);
 
    //refer: 10
    //value: 0
    cout << "refer: " << refer << "\n";
    cout << "value: " << value << "\n";
 
    return 0;
}

 

위에 C++ 코드 처럼 callByValueFunc() 함수는 단순히 value 의 값을 넘겨 함수 처리부에서 넘겨받은 값을 새로운 메모리 주소에 값을 삽입하므로 실질적으로 파라미터로 넘어온 value 값에 대한 메모리 주소와는 다른 주소를 가진다.

 

단, callByReferenceFunc() 함수에서는 refer 값의 대한 주소를 넘기고, 함수에서 메모리 주소 값을 받아와서 해당 주소에 값을 할당하므로 같은 주소에 있는 값을 변경하게 되므로 실제로 같은 메모리 주소에 대한 값을 변경하게된다.

 

C++ 에서는 이렇게 메모리 주소 값을 참조하고 shallow copy 가 일어나는 행위를 사용자가 직접 컨트롤 해야하는 반면에 Node.js 에서는 primitive data type 에 대해서는 메모리 참조를 할 수 없도록 되어있다.

 

그에 반해 immutable 한 value 가 아닌 다른 객체들에 대해서는 기본적으로 shallow copy 가 일어나게 되고 같은 메모리 주소를 참조하는 copy 방식으로 진행된다.

 

따라서 여러 변수들이 하나의 메모리 주소값을 참조하게 되면 의도하지 않게 객체를 변경할 수 있는 여지가 생겨 위험한 코드를 작성하게 될 수 있다.

 

이에 대해서 deep copy 가 일어날 수 있도록 하는 defensive copy 를 사용하는 방법이 존재하는데, Object.assign(target, ...source) 를 사용하여 deep copy 처럼 사용할 수 있다.

 

단, target 객체 내부 Nested Object 에 또 다른 mutable 한 객체가 존재하게 되면 해당 객체는 또한 shallow copy 가 되어 완전 deep copy는 불가능 하다.

반응형