C ++의 비 선택적 포인터와 비 콘스탄트 참조


12

에서 다른 C ++ 특징, 참조 인수구글 C ++ 스타일 가이드는 , 그 const가 아닌 참조는 사용할 수 없습니다 읽어 보시기 바랍니다.

참조로 전달 된 모든 매개 변수에는 const 레이블이 있어야합니다.

참조를 인수로 사용하는 함수 호출을 보는 것이 C 프로그래머에게는 혼란 스럽지만 현재 C와 C ++는 다른 언어입니다. 출력 매개 변수가 필요한 경우 , 필수 출력 매개 변수에 대한 포인터를 사용하여 전체 함수 본문을 건너 뛰어 함수 구현을 더 복잡하게 만들 수 있습니다 (공식적으로 순환 복잡도깊이 를 증가시킵니다 ).

C ++ 코드를 최대한 이해하기 쉽고 유지하기를 원하기 때문에 일반적으로 코딩 스타일 가이드를 읽는 데 관심이 있습니다. 그러나 팀의 모범 사례를 적용하려면 스타일 가이드 요소의 근거를 이해하는 것이 중요한 요소라고 생각합니다.

비 const 참조는 실제로 그렇게 나쁘습니까? 금지하는 것은 Google에만 해당되거나 일반적으로 허용되는 규칙입니까? 출력 매개 변수를 포인터로 구현하기위한 추가 노력이 필요한 이유는 무엇입니까?


2
"포인터를 사용하면 함수 본문 전체를 건너 뛰게됩니다."
ratchet freak

@ratchetfreak 나는 이것을 명확히하려고 노력했다. 나는 이와 같은 기능이 일부 디자인 결함을 보여줄 수 있음을 인정한다. 포인터는 항상 공식적으로 선택 사항이므로 참조를 해제하기 전에 확인해야합니다.
Wolf

4
Google의 C ++ 스타일 가이드는 거꾸로되어 있습니다. 내 주관적인 견해로는 불에 타야합니다.
Siyuan Ren

이 특정 항목에 관해서는, 이론적 근거는 프로그래머가 인수를 변경했을 때 앰퍼샌드를 작성하도록 강요하는 것이 분명한 의도를 보인다고 생각합니다.
Siyuan Ren

4
Google 스타일 가이드는 Google 레거시 프로젝트에서 동종 코드를 지원하기 위해 작성되었습니다. 레거시 프로젝트 (처음부터이 스타일 가이드로 작성된)에서 작업하지 않는 경우 새 코드에는 적합하지 않은 규칙을 많이 지정해야합니다 (c ++ 11, c ++ 14 , c ++ 17)).
utnapistim

답변:


18

Google 스타일 가이드의 근거는 단순히 매개 변수가 입력 매개 변수인지 또는 출력 매개 변수인지를 함수의 호출 사이트에서 명확하게하기위한 것입니다. (자세한 설명 은 여기 를 참조 하십시오 .) 다른 언어는 의도적으로 매개 변수를 명시 적으로 만듭니다. 예를 들어 C # 에는 호출 사이트에서 사용해야 하는 out키워드가 있습니다 . C ++은 명시 적으로 표현하지 않았기 때문에 Google은 const ref를 사용하기로 결정했습니다. 명확하게하기 위해 포인터 대.

이것이 Google 규칙인가요? 아니요, 그러나 그것이 매우 널리 퍼져있는 것 같습니다. Google 스타일 가이드 및 Google 스타일 가이드의 일부를 명시 적으로 준수하는 그룹 외부에서는 그것을 보지 못했다고 생각합니다. (예를 들어, 몇 년 전에 Google 스타일 가이드를 처음 읽었을 때이 아이디어가 마음에 들었고 내 코드 중 일부에 사용했습니다.)

특히, 새로 발표 된 C ++ 코어 가이드 라인 은 (거의) 모든 것에 대한 출력 매개 변수보다 반환 값을 선호하고 나머지는 비 const 참조를 사용합니다. Google에서 포인터와 참조를 사용하면 출력 매개 변수가 더 명확 해지지 만 반환 값은 더 명확합니다. C ++ 11은 표준화 된 이동 (rvalue 참조, &&많은 유형의 리턴을 저렴하게 만들기) 및 튜플 (여러 값을 리턴하는 쉬운 방법 허용)을 가지므로 매개 변수에 대한 많은 유스 케이스가 더 이상 적용되지 않습니다.

C ++ 핵심 지침에는 그 뒤에 큰 이름 (Bjarne Stroustrup, Herb Sutter)이 있으며 Microsoft에서 지원하며 최신 C ++ 기능 (Google 스타일 가이드와 달리)을 채택하므로 권장 사항이 Google보다 인기가 높을 것으로 기대합니다.


귀하의 답변에 감사드립니다 (C #에 대한 간단한 여행). 쉬운 검토는 물론 특히 오픈 소스 프로젝트에서 중요한 포인트입니다. 현대 C ++의 저렴한 수익으로 인해 이러한 고려 사항의 중요성이 사라집니다. 오래된 레거시 소프트웨어와 오래된 컴파일러를 사용하면 여전히 도움이 될 수 있습니다.
Wolf

나는 그것을 잊지 않았지만 C ++ 핵심 지침 은 빨리 얻을 수 없습니다. 그것은 있다는 흥미로운 철학 규칙 뒤에 근거도 프로그램에 현대화보기 의사 소통을하는 방법으로 ( "코드에서 직접 익스프레스 아이디어"파이썬의 선처럼 조금 읽고)을 보여줍니다.
Wolf

보충 : C ++ 코드 가이드 라인 의 철학 섹션 으로 직접 연결됩니다 .
늑대

1

전달 된 유효하지 않은 포인터, 첫 번째 확인 및 조기 반환을 처리하는 두 가지 옵션이 있거나 정의되지 않은 동작이되도록합니다 (강건성보다 속도에 더 관심이있는 경우).

확인은 다음과 같이 간단합니다.

void foo(void* buffer){
    if(buffer == nullptr)
        return;

    //actually foo

    // note no increase in indentation required

}

이 유형의 점검은 일반적으로 매개 변수 점검으로 승인됩니다. 코드가 보이면 null이 아닌 포인터가 전달되고 그렇지 않은 경우 일찍 반환 될 것으로 예상됩니다. 따라서 유효하지 않은 포인터에 대해 크게 걱정하지 않아도됩니다.


글쎄, 나는이 패턴에 대해 생각하고 절대적으로 합리적이라고 생각합니다. 슬프게도 assert(buffer);assert가 디버그 버전에서만 활성화 되어 있다는 것을 알기 때문에 때로는 rt_assert(buffer);예외가 발생 하는 것을 원합니다 . 의 들여 쓰기는 return조금 위험한 보이는 ... BTW : 당신의 코드는 출력 포인터에 대한 내 질문의 좋은 그림입니다.
Wolf

1

그것은 당신의 관찰로 귀착됩니다 If an output parameter is required.

함수 시그니처가 출력 매개 변수를 가져야하는 유일한 장소는 외부 API에 의해 지정 될 때뿐입니다. 이러한 경우 외부 API를 항상 유효한 포인트가 있는지 확인하는 것으로 랩핑하십시오.

내부적으로 리턴 유형을 모든 "출력"의 복합으로 확장하여 출력 매개 변수를 피합니다.


비 필수 포인터를 제공 할 수없는 유일한 장소입니까? 사실이지만 귀하의 규칙 The only place where...이 모든 경우에 실제로 적용 되는지 확실하지 않습니다 . 당신이 제안하는 것 : 자신의 프로그램의 기능에서 출력 매개 변수를 피하십시오. 새로운 프로그램에 적합합니다.
Wolf

1
예, 출력 매개 변수를 피하고 복합 리턴 유형을 선호하며 명확하게 편집하십시오
Caleth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.