C / C ++에서 가능한 경우 매개 변수 및 로컬 변수에 'const'를 사용해야합니까?


14

이 질문은 java 에 관한 질문 final에서 영감을 얻었습니다 .

C / C ++에서 const가능할 때마다 사용해야 합니까?

매개 변수 사용 const에 대한 관련 질문이 이미 있다는 것을 알고 있습니다 . 불행히도 그 질문과 대답은 함수 매개 변수에 관한 것이므로 다른 질문 (예 : 지역 변수)에 대해서도 알고 있기 때문에 내 질문에 완전히 대답하지 못합니다.

또한 그 질문에 대한 거의 모든 대답 const에는 변수의 접근성에 대한 유용한 정보가 들어 있기 때문에 사용해야한다고 말합니다 . 그러나 이것은 추가 정보가 포함되어 있지 않으면 불필요한 상태 일 수있는 Java에서 final을 사용하는 것에 대한 답변 과 충돌하는 것 같습니다. final따라서 코드를 짧고 깨끗하게 유지하려면 생략해야합니다.

그래서 const가능할 때마다 사용해야 합니까? 그렇다면 constC ++의 조언 final이 Java 의 조언과 다른 이유는 무엇입니까?

답변:


19

우선, Java를 참조했기 때문에 final와는 완전히 다른 짐승 const입니다. Final은 참조가 변경 될 수 없지만 변경 가능성에 대해서는 아무 것도 말하지 않습니다. Const는 훨씬 강력한 보증인 "const reference cannot mutate"을 말함으로써 더 나아갑니다. Java에서이를 수행하려면 내부 상태가 최종 상태이며 구성시 결정되어야합니다. Const는 사용하기가 훨씬 쉽고 기존 객체를 const 참조로 "승격"할 수 있습니다.

예, 가능할 때마다 const를 사용해야합니다. 코드가 변경되지 않는다는 계약을합니다. const가 아닌 변수는 const 매개 변수를 허용하는 함수에 전달할 수 있습니다. 항상 const를 추가 할 수는 있지만 제거 할 수는 없습니다 (정말 나쁜 아이디어 인 const 캐스트가 없으면).

불확실성은 때때로 지루할 수 있지만 불변성을 보장하는 데 도움이됩니다. 스레드가 객체를 공유하는 다중 스레드 코드에서 중요합니다. 특정 작업을보다 효율적으로 만듭니다. 상태를 복사하는 대신 동일한 불변 개체를 재사용하십시오. 라이브러리는 프로그래머에게 라이브러리 라이브러리의 블랙홀에서 예측할 수없는 방식으로 객체가 변경되지 않을 것이라는 보장을 제공하기 위해 const 매개 변수를 사용할 수 있습니다.


1
투표까지 당신은 설명하기 때문에 finalconst같은 보장이 없습니다.
Bill Door

2
일관성은 변경 가능성이 아니라 쓰기 가능성에 관한 것입니다.
Basilevs

@Basilevs 객체에 쓰면 어떻게됩니까? 돌연변이. 객체를 어떻게 변형 시키나요? 그것에 쓰십시오.

4
const 참조에 쓰면 어떻게됩니까? 컴파일 시간 오류 const가 아닌 다른 참조를 통해 어딘가에 참조 된 객체에 쓰면 어떻게됩니까? 돌연변이. 불변 객체는 변경할 수 없으므로 const 참조가 불변 객체를 반드시 참조 할 필요는 없습니다.
Basilevs

@Basilevs 관찰은 const 참조로만 적용됩니다. 객체 자체가 참조가 아닌 const로 선언되면 객체가 불필요하게 변하지 않는 한 불변입니다.
Matthew James Briggs

5

개인적으로, 작성하는 const데 걸리는 시간과 읽는 데 걸리는 시간이 거의 없습니다. 일반적으로 코드가 변수를 변경하는지 여부를 확인하는 것보다 훨씬 적으며 실제로 버그를 작성하지 못하게합니다 (누가 실수로 최종 반복자를 증가 시켰습니까? 기타)

또한 const 사용법을 엄격하게 사용하면 사소한 초기화를 수행하는 도우미 함수 만들기와 같은 다른 방법으로 더 나은 코드로 이끌 수 있습니다.


4

다른 포스터에 동의 하지 않고const 지역 변수 및 매개 변수에 최상위를 사용 하지 않는 것이 좋습니다 . (const에 대한 참조와 포인터 const T&는 다르므로 항상 적절할 때 정확성을 위해 사용해야합니다.)

최상위 레벨의 장점 const은 다음과 같습니다.

  • 지역 변수가 변경되지 않았 음을 분명히합니다.
  • 실수로 변경하려고하면 컴파일러 오류가 발생합니다.

단점은 다음과 같습니다.

  • 시각적 혼란.
  • "의사 -const"변수, 즉 직접 생성보다 복잡한 방식으로 초기화되었지만 다음과 같이 수정하지 않은 변수에는 사용할 수 없습니다 getline.

    std::string line; // cannot be const
    std::getline(std::cin, line);
    // line should be const from here on out
  • 함수 호출 및 리턴시 이동 최적화를 방지합니다.

    std::string f1();
    std::string f2(std::string s);
    std::string f3() {
      const std::string s = f1(); // s is not meant to be modified
      // but I still want the move optimization here:
      const std::string result = f2(std::move(s)); // this doesn't move
      // and I want the compiler to move out here:
      return result; // this will probably RVO, but if not, the move
                     // constructor will not be used due to the const
    }

로컬 const이 많이 사용되는 코드베이스에서 작업 했지만 전혀 도움이되지 않지만 위와 같이 미묘한 비관으로 코드를 채 웠습니다. 나는 개인적으로 변수를 가능한 한 거의 수정하지 않는 일반적인 정책을 채택하고 변수의 사용법이 분명 할 정도로 함수를 작게 만드는 것을 선호하며, 수정하더라도 함수의 복잡성이 낮아서 -발행물.


2
이동에 대한 요점은 당신이 (
의도적으로)

1
@Caleth 아니오, 그게 요점입니다. 나는 그것을 수정하려고하지 않습니다. 값을 전달하거나 반환하고 싶고 효율적이기를 원합니다. 개념적으로, 수정은 단지 최적화 일 뿐이며, 변수는 나중에 사용되지 않기 때문에 관찰 할 수 없습니다. 실제로 C ++에는 Rust와 같은 진정한 파괴적인 움직임이 없으므로 수정이 있습니다. 그것이 바로 const현지인들이 원하지 않는 이유 입니다. 개념적 수정이 아닌 기술적 인 수정을 막기 때문입니다.
Sebastian Redl

2
당신은 수정하지 않는 값을 ,하지만 당신은 수행 수정할 변수를 . 대신 const &를 대신 사용하거나 수정하지
않아도됩니다.

2

const키워드는 매개 변수와 같은 지역 변수를 사용해야합니다. 다음과 같은 이유로 유용합니다.

  • 코드를보다 쉽게 ​​읽을 수 있습니다. 누군가 변수 선언을 읽으면 변경되지 않는다는 것을 알게됩니다. 코드를 읽는 동안 걱정할 것이 하나도 없습니다.
  • 실수로 변수를 수정하지 못하게하십시오.
  • 런타임 패널티가 없으며 모든 것이 정적으로 검사됩니다. 무료 점심 식사처럼 작성하는 const데 1 초 밖에 걸리지 않으므로 별 문제가 없습니다.
  • 멀티 스레드 응용 프로그램에서 변수 / 매개 변수를 만드는 것이 항상 좋습니다. 응용 프로그램이 멀티 스레드가 아니더라도 여전히 좋은 습관입니다.
  • C ++ 컴파일러가 코드를 최적화 할 수있는 기회를 제공합니다.

여기에는 정답 / 오답이 없습니다. 귀하의 링크에서 가장 많이 주장 된 답변자는 final현지에서 사용해서는 안됩니다. 그러나 다음 답변자는 강력히 추천했습니다.

당신의 기능이 단순 하고 사소한 경우 , const모든 사람이 당신의 의도를 이해하기 때문에 추가해서는 안됩니다 . 그러나 함수의 논리가 중요하지 않은 경우 키워드를 사용해야합니다. 잃을 것이 거의 없다는 것을 기억하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.