문제

함수 선언과 그 정의가 값 매개 변수에 대해 동의 할 필요가 없다고 언급 된 Const 정확성에 대한 질문이 거의 없다는 것을 알고 있습니다. 이는 값 매개 변수의 콘트니스가 함수 내부에서만 중요하기 때문입니다. 이건 괜찮아:

// header
int func(int i);

// cpp
int func(const int i) {
    return i;
}

이것을하는 것이 정말 모범 사례입니까? 나는 아무도 그것을 본 적이 없기 때문에. 다른 장소 에서이 인용문 (소스를 확실하지 않음)을 보았습니다.

"실제로 컴파일러에게는 기능 서명이 값 매개 변수 앞에이 const를 포함하든 아니든 동일합니다."

"함수 선언에서 const pass-by-value 매개 변수를 피하십시오. 수정되지 않으면 동일한 함수의 정의에서 매개 변수를 동일한 매개 변수로 만듭니다."

두 번째 단락은 Const를 선언에 넣지 말라고 말합니다. 나는 이것이 값 매개 변수의 콘트니스가 인터페이스 정의의 일부로 의미가 없기 때문이라고 생각합니다. 구현 세부 사항입니다.

이 권장 사항을 기반으로 포인터 매개 변수의 포인터 값에도 권장됩니까? (참조 매개 변수는 참조를 재 할당 할 수 없기 때문에 의미가 없습니다.)

// header
int func1(int* i);
int func2(int* i);

// cpp
int func1(int* i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compiles without error

    return *i;
}
int func2(int* const i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compile error

    return *i;
}

요약: 값 매개 변수를 만드는 것은 논리 오류를 포착하는 데 유용합니다. 모범 사례입니까? 헤더 파일에서 const를 남겨 두는 극단으로 이동합니까? Const 포인터 값에 유용합니까? 그 이유는 무엇?

일부 참조 :

C ++ const 키워드 - 자유롭게 사용하십니까? 함수 매개 변수에 'const'사용

const 값 매개 변수가 유용한시기의 예 :

bool are_ints_equal(const int i, const int j) {
    if (i = j) { // without the consts this would compile without error
        return true;
    } else {
        return false;
    }
    // return i = j; // I know it can be shortened
}
도움이 되었습니까?

해결책

내 테이크 :

나쁜 생각은 아니지만 문제는 미미하고 에너지는 다른 것들에 더 잘 소비 될 수 있습니다.

귀하의 질문에서 당신은 그것이 오류를 잡을 때의 좋은 예를 제공했지만 때로는 다음과 같은 일을하게됩니다.

void foo(const int count ...)
{
   int temp = count;  // can't modify count, so we need a copy of it
   ++temp;

   /* ... */
}

장단점은 어느 쪽이든 사소한 방법입니다.

다른 팁

나는 함수에서 값 매개 변수를 만드는 것이 불필요하기 때문에 나쁜 일이라는 것을 여러 번 읽었습니다.

그러나, 나는 내 구현이 내가 의도하지 않는 일을하지 않는다는 점검으로 가끔 도움이된다는 것을 알게된다 (질문 끝의 예에서와 같이).

따라서 발신자에게 가치를 더할 수는 없지만 때로는 구현 자로서 나에게 약간의 가치가 추가되며 발신자로부터 아무것도 빼앗아 가지 않습니다. 그래서 나는 그것을 사용하는 데 해를 끼치 지 않습니다.

예를 들어, 몇 개의 포인터를 버퍼로 가져 오는 C 함수를 구현할 수 있습니다 - 시작에 대한 포인터, 그리고 끝에 대한 포인터. 버퍼에 데이터를 넣을 것입니다. 그러나 끝을 오버런하지 않도록하고 싶습니다. 따라서 함수 내에는 데이터를 추가 할 때 포인터를 증가시키는 코드가 있습니다. 버퍼의 끝에 포인터를 만들기 const 매개 변수는 실수로 포인터 대신에 끝 경계 포인터를 증가시키는 버그를 코딩하지 않도록합니다.

따라서 FillArray는 다음과 같은 서명으로 기능합니다.

size_t fillArray( data_t* pStart, data_t* const pEnd);

실수로 증가하지 못하게합니다 pEnd 내가 정말로 증가한다는 것을 의미 할 때 pStart. 그것은 큰 일이 아니지만, 나는 C에서 일정 기간 동안 프로그래밍 한 모든 사람들이 그러한 버그를 가로 질러 실행했다고 확신합니다.

불행히도, 일부 컴파일러 (나는 당신을보고 있습니다, Sun CC!)는 Const가 선언 된 인수와 그렇게 선언하지 않은 인수를 잘못 구별하면 정의되지 않은 함수에 대한 오류를 얻을 수 있습니다.

나는 이것이 당신의 개인 스타일에 달려 있다고 생각합니다.

클라이언트가 기능에 전달할 수있는 것을 추가하거나 빼지 않습니다. 본질적으로 그것은 컴파일 타임 주장과 같습니다. 가치가 변하지 않을 것이라는 것을 알 수 있도록 도와 주면 계속해서하십시오. 그러나 다른 사람들이 그렇게해야 할 큰 이유는 없습니다.

내가 그렇게하지 않을 수도있는 한 가지 이유는 값 매개 변수의 구성이 고객이 알 필요가없는 구현 세부 사항이기 때문입니다. 나중에 (의도적으로) 기능이 실제로 해당 값을 변경하도록 기능을 변경하면 기능의 서명을 변경하여 고객이 재 컴파일을 강요해야합니다.

이는 일부 사람들이 공개 가상 방법이없는 것을 권장하는 이유와 유사하지만 (기능은 가상은 클라이언트로부터 숨겨져야하는 구현 세부 사항입니다), 나는 그 특정 캠프에 있지 않습니다.

Const 키워드가있는 경우; 이는 'i'(const 유형)의 값을 수정할 수 없음을 의미합니다. FOO 기능 컴파일러 내부에서 'I'값이 변경되면 오류가 발생합니다. "

Const 객체를 수정할 수 없습니다

그러나 ' *i'(예 : *i = 3;)를 바꾸는 것은 'i'의 가치를 바꾸는 것이 아니라 'i'로 가리키는 주소의 가치를 의미한다는 것을 의미합니다.

실제로, const 함수는 함수별로 변경되지 않아야하는 큰 객체에 적합합니다.

우리 모두는 때때로 다른 사람의 C ++ 코드를 풀어야합니다. 그리고 다른 사람의 C ++ 코드는 정의에 따라 완전한 혼란입니다. d.

그래서 내가 항상 그것을 해독하기 위해 내가하는 첫 번째 일은 (로컬 및 글로벌 데이터 흐름) const 컴파일러가 불평 할 때까지 모든 변수 정의에서. 이것은 또한 자격을 갖추는 가치 주장을 의미하며, 사실상 눈치 채지 않고 함수의 중간에 수정 된 변수를 피하는 데 실제로 도움이됩니다 ...

그래서 다른 사람이 모든 곳에서 const를 가지고있을 때 (가치 매개 변수 포함) : D

나는 다음과 같은 상황에 대한 const 정확성을 좋아합니다.
void foo(const Bar &b) //I know b cannot be changed
{
//do something with b
}

이것은 내가 사용할 수있게한다 b 수정에 대한 두려움 없이는 사본 생성자의 비용을 지불 할 필요가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top