2012-01-03 2 views
83

const의 목적은 무엇입니까?const 값으로 반환하는 목적은 무엇입니까?

const Object myFunc(){ 
    return myObject; 
} 

난 그냥 효과적인 C++ 및 항목을 읽기 시작했습니다 3 옹호자이와 Google 검색이 유사한 제안뿐만 아니라 반례를 선택합니다. 나는 여기서 const를 사용하는 것이 어떻게 더 바람직한 지 알 수 없다. 값으로 반환한다고 가정하면 반환 된 값을 보호 할 이유가 없습니다. 이것이 도움이 될 수있는 이유에 대한 예제는 의도하지 않은 반환 값의 bool 캐스트를 방지하는 것입니다. 실제 문제는 암시 적 bool 캐스트가 명시 적 키워드로 방지되어야한다는 것입니다.

const를 사용하면 할당하지 않고 임시 개체를 사용할 수 없습니다. 그래서 나는 그 객체들로 산술 식을 수행 할 수 없었다. 이름없는 const가 유용 할 때도있는 것처럼 보이지 않습니다.

여기에서 const를 사용하면 무엇을 얻을 수 있습니까?

편집 : 할당 전에 수행 할 수있는 개체를 수정하는 함수로 산술 예제를 변경하십시오.

+1

예 산술 연산자가 const 여야하고 const 개체도 반환해야하기 때문에 const 개체를 사용하여 산술을 수행 할 수 있습니다. –

답변

87

는 실수로 호출하지 못하도록 이 작업은 임시로 수행됩니다. +는 const가 아닌 값을 반환 상상해, 당신은 쓸 수 :

(a + b).expensive(); 

를 C++ 11 세의 나이에, 그러나, 강력 전체 취할 수 있도록 const가 아닌 같은 값을 반환하는 것이 좋습니다 rvalue 참조의 장점. 비 rvalues에 대해서만 의미가 있습니다.

요약하면, 이 관행의 근거이지만 본질적으로 쓸모가 없습니다.

+0

글쎄, Herb Sutter [권장되는 반환 값] (http://books.google.com/books?id = 58rZvOSuheEC & lpg = PA179 & ots = L_LgismXMo & dq = sutter % 20return % 20const % 20value & pg = PA179 # v = onepage & q & f = false) 비 기본 유형의 경우,하지만 지금은 조언이 쓸모 없다고 생각합니다. –

+10

@FredLarson : 네, 14 세의 책에서 : - –

+0

이 답은 const 값으로 반환한다는 것은 const &&를 의미하지만 실제로 맞습니까? 예 : VS13을 사용하면 int && var =를 const int를 반환하는 함수에 바인딩 할 수 있습니다. "반환 유형이 참조가 아닌 함수를 호출 한 결과는 prvalue입니다." –

32

It's prettypointless 함수에서 const 값을 반환합니다. 이 모든인지 여부를

struct T {}; 

const T foo() { 
    return T(); 
} 

int main() { 
    foo() = T(); 
} 

// error: passing ‘const T’ as ‘this’ argument of ‘T& T::operator=(const T&)’ discards qualifiers 

는 의심의 :

const int foo() { 
    return 3; 
} 

int main() { 
    int x = foo(); // copies happily 
    x = 4; 
} 

and :

const int foo() { 
    return 3; 
} 

int main() { 
    foo() = 4; // not valid anyway for built-in types 
} 

// error: lvalue required as left operand of assignment 

you can notice if the return type is a user-defined type 비록

그것은 당신의 코드에 어떤 영향을 미칠 얻을 difficult입니다 누구에게나 이익이된다.

참조를 반환하는 것은 다르지만 Object이 일부 템플릿 매개 변수가 아니라면 그렇게하지 않는 것입니다.

+0

두 번째 예제는 기본 제공 유형에 대해서만 오류를 트리거합니다. – Xeo

+0

첫 번째 예를 자세히 설명해 주시겠습니까? 반환 값이 const가 될 것이지만 그것을 const가 아닌 변수에 할당 할 수 있다고 말하는 것은 나에게 의미가 없습니다. –

+1

@IvayloToskov : 당신이 필요로하는 모든 노력은 예를 들어, 특히 "행복하게 복사"하는 주석입니다. const int x = 4; int y = x;'또한 완벽하게 괜찮습니다. –

-2

개인 상수 데이터 형식에 대한 참조를 반환하는 래퍼 함수로 사용할 수 있습니다. 예를 들어 링크드리스트에서 tail과 head라는 상수가 있고 노드가 꼬리 또는 머리 노드인지 확인하려면 해당 함수가 반환 한 값과 비교할 수 있습니다. const를 값으로 반환 어떤 최적화가 가장 가능성이 어쨌든을 최적화 할 비록

... 당신이 객체에 잠재적으로 비용이 const가 아닌 작업을 수행 할 수있는 가상의 상황에서

+0

하지만 그는 객체를 반환하고 있습니다. –

+0

최적화 할 것이 아무것도 없으며, const-ness는 컴파일 타임 안전 메커니즘입니다. –

+0

아, Object *로 잘못 읽었습니다. ... –

-3

myObject는 포인터 일 수 있습니다. 'const'는 myObject가 가리키는 값을 보호합니다.

+3

사실, 아니요. 'Object const *'는'Object * const'가 아닙니다. –

3

반환 된 개체 (해당 시점의 RValue)는 수정할 수 없습니다. 이것은 할 수없는 사용자가이 같은 생각 확인합니다 :

myFunc() = Object(...); 

잘 작동합니다 참조로 반환하지만, 거의 확실 값에 의해 반환 된 버그 myFunc 경우 (그리고 아마도에 의해 체포되지 않습니다 컴파일러). 물론 그것의 rvalues와 C + + 11에서,이 컨벤션은 const 객체가 옮겨 질 수 없기 때문에 이전처럼 많은 의미를 가지지 않으므로 성능에 상당한 영향을 미칠 수 있습니다.

+0

그것은'const'를 설명하지 않습니다. –

+0

@ Nicol Bolas : 어떻게 const를 설명하지 않습니까? 반환 유형이'Object' 인 경우 컴파일하는 동안의 코드 예제입니다. 그러나 'const Object' 인 경우가 아닙니다. – Grizzly

+0

아마도 "_xvalues_와 함께 C++ 11"을 의미할까요? (_xvalues_와 _prvalues_는 둘 다 _rvalues_이지만 중요한 차이점 인 C++ 11의 새로운 _xvalues_입니다.) –

1

C++ 11은 이동 전용 개체에 유용합니다. 예를 들어 :

const std::unique_ptr<T> myFunc(); 

unique_ptr 복사 할 수없는 종류의 파일입니다; 그것은 단지 움직일 수 있습니다. 그러나 const 유형에서는 std::move으로 전화 할 수 없습니다. 따라서이를 저장할 수있는 유일한 방법은 const& 또는 const&& 함께 :

const std::unique_ptr<T> &ptr = myFunc(); 

그것은 const unique_ptr 이래로, 그것은에서 이동할 수 없습니다. 또한 복사 할 수 없습니다. 어떤 의미에서 그것은 매우 장기간 실제로 저장할 수 없다는 것을 의미합니다. 스택에 놓을 수 있습니다. 그러나 그것을 클래스의 멤버로 만드는 것은 (정의되지 않은 동작을 호출하지 않고) 불가능합니다.

이렇게하면 포인터가 장기간 저장되지 않을 수 있습니다. 이렇게하면 삭제자인 unique_ptr의 특수 버전을 만들면 실제로 메모리가 삭제되지 않습니다. 그런 식으로 함수는 사용자가 어디에도 저장할 수 없다는 것을 알고 포인터를 반환 할 수 있습니다.

물론 이것은 호출자가 값을 반환하기가 다소 어렵습니다. 그래서 단점이 있습니다.

+1

죄송 합니다만, 먼저 downvote해야합니다 - 먼저 * 변수 *를 저장할 수 있습니다 -term - 특히 전역 또는 함수 정적 또는 스레드 로컬 변수에서. 둘째, rvalue가 로컬 참조에 바인딩되어 있다고하더라도 해당 함수가 프로그램이 끝날 때까지 실행되지 않습니다. 셋째, 호출자의 삶을 어렵게 만드는 것은 매우 바보 같은 일입니다. 그리고 네 번째로, pointee를 지우지 않는'unique_ptr'을 만드는 것이 가능합니다 - pointee가 포인터보다 오래 지속될 수 있는지 확인해야합니다 (예를 들어, 전역 변수). 장치가이 보증을 지원하지 않습니다. – jpalecek

+0

기다려 주시겠습니까? 즉시 파괴 된 임시에 대한 참조를 저장하고 있습니까? 그것은 심지어 컴파일합니까? –

+2

@EmilyL. 임시에 대한 const 참조는 수명을 연장 할 수 있습니다. https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-most-important-const/을 참조하십시오. – tomjakubowski

관련 문제