포인터 대 참조
함수에 원래 변수를 제공 할 때 더 나은 방법은 무엇입니까?
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
또는:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
IOW : 다른 것을 골라야 할 이유가 있습니까?
내 경험 법칙은 다음과 같습니다.
포인터를 사용하여 포인터 산술을 수행하려는 경우 (예 : 배열을 통해 포인터 주소를 증가시키는 경우) 또는 NULL 포인터를 전달해야하는 경우 포인터를 사용하십시오.
그렇지 않으면 참조를 사용하십시오.
코딩 가이드 라인을 호출하는 다음 함수를 설정하면 도움이 될 것입니다.
다른 모든 장소와 마찬가지로 항상
const
정확해야합니다.- 참고 : 이는 특히 값을 벗어난 값 (항목 3 참조)과 값을 통해 전달 된 값 (항목 4 참조)에만
const
지정자가 부족함을 의미 합니다.
- 참고 : 이는 특히 값을 벗어난 값 (항목 3 참조)과 값을 통해 전달 된 값 (항목 4 참조)에만
현재 컨텍스트에서 0 / NULL 값이 유효한 입력 인 경우에만 포인터로 값을 전달하십시오.
근거 1 : 발신자 로서 , 당신은 당신이 전달하는 것이 사용 가능한 상태 에 있어야 한다는 것을 알 수 있습니다.
이유 2 :로는 전화 당신이 들어오는 어떤 것을 알고, 이다 가능한 상태. 따라서 해당 값에 대해 NULL 점검 또는 오류 처리를 수행 할 필요가 없습니다.
이론적 근거 3 : 이론적 근거 1과 2가 컴파일러에 의해 시행 될 것이다 . 가능하면 컴파일 타임에 항상 오류를 잡으십시오.
함수 인수가 값을 벗어나면 참조로 전달하십시오.
- 근거 : 우리는 아이템 2를 깨고 싶지 않다 ...
값이 POD ( Plain old Datastructure )이거나 작거나 (메모리 단위) 또는 다른 방법으로 복사 할 수있을만큼 (시간 단위) 값이 작은 경우에만 "pass by const reference"대신 "value by pass"를 선택하십시오 .
- 근거 : 불필요한 사본을 피하십시오.
- 참고 : 작은 충분 하고 저렴한 충분 절대 measurables 수 없습니다.
이것은 결국 주관적입니다. 지금까지의 논의는 유용하지만 이것에 대한 정답이나 결정적인 대답은 없다고 생각합니다. 많은 것은 스타일 가이드 라인과 당시의 요구에 달려 있습니다.
포인터와 함께 몇 가지 다른 기능 (무엇이 NULL이 될 수 있든 없든)이 있지만 출력 매개 변수의 실질적인 차이점은 순전히 구문입니다. 예를 들어 Google의 C ++ 스타일 가이드 ( https://google.github.io/styleguide/cppguide.html#Reference_Arguments )는 출력 매개 변수에 대한 포인터 만 요구하고 const 인 참조 만 허용합니다. 추론은 가독성 중 하나입니다. 값 구문이있는 것은 포인터 의미 의미를 가져서는 안됩니다. 나는 이것이 반드시 옳고 그름이라는 것을 제안하는 것은 아니지만, 여기서의 요점은 그것이 정확함이 아니라 스타일의 문제라는 것입니다.
변수 값을 수정하려면 포인터를 전달해야합니다. 기술적으로 참조 또는 포인터를 전달하는 것은 동일하지만 사용 사례에서 포인터를 전달하면 값이 함수에 의해 변경된다는 사실을 "광고"하므로 더 읽기 쉽습니다.
값이 없음을 표시해야하는 매개 변수가있는 경우 매개 변수를 포인터 값으로 만들고 NULL로 전달하는 것이 일반적입니다.
대부분의 경우 (안전 측면에서) 더 나은 솔루션은 boost :: optional 을 사용하는 것 입니다. 이를 통해 참조 값과 반환 값으로 선택적 값을 전달할 수 있습니다.
// Sample method using optional as input parameter
void PrintOptional(const boost::optional<std::string>& optional_str)
{
if (optional_str)
{
cout << *optional_str << std::endl;
}
else
{
cout << "(no string)" << std::endl;
}
}
// Sample method using optional as return value
boost::optional<int> ReturnOptional(bool return_nothing)
{
if (return_nothing)
{
return boost::optional<int>();
}
return boost::optional<int>(42);
}
가능하면 참조를 사용하고, 필요할 때 포인터를 사용하십시오. 에서 C ++ FAQ : "나는 포인터를 사용해야 할 때 언제 참조를 사용한다?"
포인터
- 포인터는 메모리 주소를 보유하는 변수입니다.
- 포인터 선언은 기본 유형, * 및 변수 이름으로 구성됩니다.
- 포인터는 일생 동안 여러 변수를 가리킬 수 있습니다
현재 유효한 메모리 위치를 가리 키지 않는 포인터에는 null 값이 제공됩니다 (0 인 경우).
BaseType* ptrBaseType; BaseType objBaseType; ptrBaseType = &objBaseType;
&는 피연산자의 메모리 주소를 반환하는 단항 연산자입니다.
역 참조 연산자 (*)는 포인터가 가리키는 변수에 저장된 값에 액세스하는 데 사용됩니다.
int nVar = 7; int* ptrVar = &nVar; int nVar2 = *ptrVar;
참고
참조 (&)는 기존 변수의 별칭과 같습니다.
참조 (&)는 자동으로 역 참조되는 상수 포인터와 같습니다.
일반적으로 함수 인수 목록 및 함수 반환 값에 사용됩니다.
참조를 만들 때 초기화해야합니다.
객체에 대한 참조가 초기화되면 다른 객체를 참조하도록 변경할 수 없습니다.
NULL 참조는 가질 수 없습니다.
const 참조는 const int를 참조 할 수 있습니다. const 값을 가진 임시 변수로 수행됩니다.
int i = 3; //integer declaration int * pi = &i; //pi points to the integer i int& ri = i; //ri is refers to integer i – creation of reference and initialization
참조는 암시 적 포인터입니다. 기본적으로 참조가 가리키는 값을 변경할 수 있지만 다른 것을 가리 키도록 참조를 변경할 수는 없습니다. 따라서 내 2 센트는 매개 변수의 값만 변경하려면 참조로 전달하지만 다른 객체를 가리 키도록 매개 변수를 변경 해야하는 경우 포인터를 사용하여 매개 변수를 전달해야한다는 것입니다.
C #의 out 키워드를 고려하십시오. 컴파일러는 out 키워드를 이미 알고 있지만 out 키워드를 out 인수에 적용하려면 메소드 호출자가 필요합니다. 가독성을 높이기위한 것입니다. 현대의 IDE에서는 구문 (또는 의미 론적) 강조의 작업이라고 생각합니다.
전달하는 내용을 변경 / 유지하려는 이유가없는 경우 const 참조로 전달하십시오.
대부분의 경우 가장 효율적인 방법입니다.
변경하지 않으려는 각 매개 변수에 const를 사용해야합니다.이 기능은 함수에서 바보 같은 일을하지 못하게 할뿐만 아니라 다른 사용자에게 전달 된 값에 대한 기능을 다른 사용자에게 잘 보여줍니다. 이것은 당신이 지적한 것을 바꾸고 싶을 때 포인터 const를 만드는 것을 포함합니다 ...
포인터 :
- 할당 할 수 있습니다
nullptr
(또는NULL
). - 콜 사이트에서
&
유형이 포인터 자체가 아닌 경우 객체를 수정하고 명시 적으로 작성해야합니다. - 포인터는 리바운드 될 수 있습니다.
참고 문헌 :
- null 일 수 없습니다.
- 바인드되면 변경할 수 없습니다.
- 발신자는을 명시 적으로 사용할 필요가 없습니다
&
. 매개 변수가 수정되었는지 확인하려면 함수 구현으로 이동해야하기 때문에 때로는 나쁜 것으로 간주됩니다.
참조는 참조가 참조하는 값에 액세스하기 위해 접두사 *를 사용할 필요가 없다는 점을 제외하면 포인터와 유사합니다. 또한 초기화 후에 다른 객체를 참조하도록 참조 할 수 없습니다.
참조는 함수 인수를 지정하는 데 특히 유용합니다.
자세한 내용은 "Bjarne Stroustrup"의 "C ++ 둘러보기"(2014) 페이지 11-12를 참조하십시오.
참고 URL : https://stackoverflow.com/questions/114180/pointer-vs-reference
'IT story' 카테고리의 다른 글
키로 해시 정렬, 루비에서 해시 반환 (0) | 2020.04.06 |
---|---|
엔티티 프레임 워크 코드 첫 번째-동일한 테이블에서 두 개의 외래 키 (0) | 2020.04.06 |
ReactiveCocoa vs RxSwift-장단점? (0) | 2020.04.06 |
유창하고 쿼리 표현-서로에 대한 이점이 있습니까? (0) | 2020.04.06 |
Xcode 6 스토리 보드의 "여백에 구속"이란 무엇입니까 (0) | 2020.04.06 |