본문 바로가기
C.C++/전반

파라미터에서 Pointer, Reference

by 겜게준 2017. 6. 22.

template <typename T> void bar(T * pTy){ pTy = nullptr; } template <typename T> void gildong(T & rTy){ rTy = nullptr; }


C에는 pass-by-reference가 없다. 단지 pointer를 이용하여 주소를 복사하고 함수에서는 복사된 주소값을 이용하여 pass-by-reference처럼 보이게 동작하는 것이다.


뭐 개념적으로 본다면 위의 동작을 pass-by-reference라고 할 수 있을 것이다.


이것은 의견이 분분하니 넘어가도록 하고


결론적으로 위의 bar 함수는 지역변수 pTy에 nullptr을 대입할 뿐이다. 그리고 기대하던 결과는 나오지 않을 것이다.


문법은 코드를 읽기 쉽게 해준다. c++의 references도 그러한 역활을 하고 있다. 포인터와는 다르게 역참조를 위하여 *와 ->를 사용하지 않아도 된다. 왜냐면 해당 메모리블럭에 대한 alias를 추가하는 것 이기 때문이다. 포인터를 조작하는게 많아 질수록 코드는 *와 ->연산자로 뒤덮일 수 있다.


인자를 reference로 가져 올 경우에는 pointer와 똑같이 동작을 하게 된다 (물론 이는 컴파일러에 따라서 다를 수 있음). 어셈 코드가 동일하다. 다시말해 인자를 pointer로 받는 reference로 받든 아무런 차이가 없다. 차이점이라면 reference는 const라는 점이 있을것이다.


safe-release의 모습들이다.



(null check 어쩌구 하는데, free도 그렇지만 delete에 null 넣으면 아무 동작 안합니다.)

template <typename T> void delete_something(T **pTy){ delete (*pTy); (*pTy) = nullptr; } template <typename T> void delete_something(T &rTy){ delete rTy; rTy = nullptr; }



그러나 누구나 그렇듯 다른 생각을 가진 사람들도 있다.


Reference Arguments

All parameters passed by reference must be labeled const.

Definition: 

In C, if a function needs to modify a variable, the parameter must use a pointer, eg int foo(int *pval). In C++, the function can alternatively declare a reference parameter: int foo(int &val).


Pros:

Defining a parameter as reference avoids ugly code like (*pval)++. Necessary for some applications like copy constructors. Makes it clear, unlike with pointers, that a null pointer is not a possible value.


Cons:

References can be confusing, as they have value syntax but pointer semantics.


Decision:

Within function parameter lists all references must be const:

void Foo(const string &in, string *out);

In fact it is a very strong convention in Google code that input arguments are values or const references while output arguments are pointers. Input parameters may be const pointers, but we never allow non-const reference parameters except when required by convention, e.g.,swap().

However, there are some instances where using const T* is preferable to const T& for input parameters. For example:

  • You want to pass in a null pointer.
  • The function saves a pointer or reference to the input.

Remember that most of the time input parameters are going to be specified as const T&. Using const T* instead communicates to the reader that the input is somehow treated differently. So if you choose const T* rather than const T&, do so for a concrete reason; otherwise it will likely confuse readers by making them look for an explanation that doesn't exist.


구글에서는 참조형식의 의미가 포인터이지만, 참조형식을 사용할 때의 문법이 값 형식을 다룰때와 같기 때문에 헷갈릴 경우가 있다고 한다. 그렇기 때문에 인자에서의 참조형식은 const 참조형식 (결과적으로 const 참조형식은 값 형식과 비슷하기 때문에) 만 사용한다고 한다.


아무튼


알아서 하자.

'C.C++ > 전반' 카테고리의 다른 글

RAII  (0) 2018.05.23
다차원 배열  (0) 2017.06.20
네이밍  (2) 2017.05.06

댓글