문제

함수가 객체의 상태를 변경할 수 없다는 것을 이해하지만 컴파일러가 동일한 인수로 함수를 호출하면 동일한 값을 반환하므로 재사용할 수 있다고 가정할 수 있다는 내용을 어딘가에서 읽었습니다. 사용 가능한 경우 캐시된 값입니다.예를 들어

class object
{
    int get_value(int n) const
    {
        ...
    }

...


object x;

int a = x.get_value(1);
    ...
int b = x.get_value(1);

그런 다음 컴파일러는 두 번째 호출을 최적화하고 레지스터의 값을 사용하거나 간단히 수행할 수 있습니다. b = a;

이것이 사실입니까?

도움이 되었습니까?

해결책

const 구현 세부 사항이 아니라 프로그램 의미에 관한 것입니다.멤버 함수를 표시해야 합니다. const 객체의 표시 상태를 변경하지 않고 객체 자체에서 호출 가능해야 하는 경우 const.내 const 클래스의 멤버 함수 X, 유형 this ~이다 X const *:상수에 대한 포인터 X 물체.따라서 모든 멤버 변수는 효과적으로 const 해당 멤버 함수 내에서(예외 mutable 것).당신이 가지고 있다면 const 개체, 당신은 호출할 수 있습니다 const 그것에 대한 멤버 기능.

당신이 사용할 수있는 mutable 멤버 변수가 그룹 내에서도 변경될 수 있음을 나타냅니다. const 회원 기능.이는 일반적으로 결과 캐싱에 사용되는 변수 또는 뮤텍스와 같이 실제 관찰 가능한 상태에 영향을 주지 않는 변수를 식별하는 데 사용됩니다(여전히 뮤텍스를 잠가야 함). const 멤버 함수) 또는 카운터를 사용하세요.

class X
{
    int data;
    mutable boost::mutex m;
public:
    void set_data(int i)
    {
        boost::lock_guard<boost::mutex> lk(m);
        data=i;
    }
    int get_data() const // we want to be able to get the data on a const object
    {
        boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
        return data;
    }
};

직접적으로 데이터를 보관하는 대신 포인터로 데이터를 보관하는 경우(예: 스마트 포인터 포함) std::auto_ptr 또는 boost::shared_ptr) 그러면 포인터는 다음과 같습니다. const 안에 const 멤버 함수는 가리키는 데이터가 아니므로 가리키는 데이터를 수정할 수 있습니다.

캐싱의 경우:일반적으로 컴파일러는 호출 사이에 상태가 변경될 수 있기 때문에 이를 수행할 수 없습니다(특히 뮤텍스를 사용하는 다중 스레드 예제에서).그러나 정의가 인라인인 경우 컴파일러는 코드를 호출 함수로 끌어오고 거기에서 볼 수 있는 내용을 최적화할 수 있습니다.이로 인해 다음 기능이 발생할 수 있습니다. 효과적으로 한 번만 호출됩니다.

다음 버전의 C++ 표준(C++0x) 새로운 키워드가 생길 거예요 constexpr.태그된 기능 constexpr 결과를 캐시할 수 있도록 상수 값을 반환합니다.이러한 함수에서 수행할 수 있는 작업에는 제한이 있습니다(컴파일러가 이 사실을 확인할 수 있도록 하기 위해).

다른 팁

키워드 변하기 쉬운 멤버 변수에서는 const 함수가 현재 객체의 상태를 변경할 수 있습니다.

아니요, 다음 코드는 시간이 지남에 따라 변경되는 유효한 const 함수이므로 데이터(적어도 모든 호출은 아님)를 캐시하지 않습니다.

int something() const { return m_pSomeObject->NextValue(); }

포인터는 const일 수 있지만 가리키는 개체는 const가 아니므로 SomeObject에서 NextValue를 호출하면 자체 내부 상태가 변경되거나 변경되지 않을 수 있습니다.이로 인해 함수가 호출될 때마다 다른 값을 반환하게 됩니다.

그러나 컴파일러가 const 메서드와 어떻게 작동하는지 대답할 수 없습니다.특정 사항을 최적화할 수 있다고 들었지만 확실하게 알아보려면 검색해야 합니다.

아니요.

const 메소드는 객체의 상태를 변경하지 않는 메소드입니다(예:해당 필드), 그러나 동일한 입력이 주어지면 const 메서드의 반환 값이 결정된다고 가정할 수는 없습니다.다시 말해서, const 키워드는 함수가 일대일임을 의미하지 않습니다.예를 들어 현재 시간을 반환하는 메서드는 const 메서드이지만 반환 값은 호출 간에 변경됩니다.

멤버 함수의 const 키워드는 이것 매개변수를 상수로 지정합니다.이 함수는 여전히 전역 데이터를 음소거할 수 있지만(그래서 캐시할 수 없음) 개체 데이터는 그렇지 않습니다(const 개체에 대한 호출 허용).

이러한 맥락에서, const 멤버 함수는 다음을 의미합니다. this 로 취급된다 const 포인터도요.실제로는 상태를 수정할 수 없다는 의미입니다. this 안에 const 회원 기능.

부작용이 없는 기능(즉, 달성하려는 기능)을 위해 GCC에는 "함수 속성"이 있습니다. pure (당신은 다음과 같이 사용합니다. __attribute__((pure))): http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

나는 함수가 여전히 세계의 상태를 변경하고 const를 위반하지 않는 전역 함수를 호출할 수 있는지 의심합니다.

멤버 함수가 전역 데이터를 수정할 수 있다는 사실 외에도 멤버 함수가 해당 개체의 명시적으로 선언된 변경 가능한 멤버를 수정할 수도 있습니다.

Corey의 말이 맞습니다. 그러나 다음과 같이 표시된 모든 멤버 변수는 변하기 쉬운 ~할 수 있다 const 멤버 함수에서 수정될 수 있습니다.

이는 또한 이러한 함수가 다른 const 함수나 다른 const 참조를 통해 호출될 수 있음을 의미합니다.


편집하다:젠장, 9초나 맞았어....9!!!:)

const 메소드는 정적 지역을 수정할 수도 있습니다.예를 들어, 다음은 완전히 합법적입니다(bar()에 대한 반복 호출은 캐시된 0이 아닌 증가하는 값을 반환합니다).

class Foo
{
public:
    int bar() const
    {
        static int x = 0;
        return x++;
    }
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top