는'변경 가능한'키워드가 이외의 다른 목적으로 허용하는 변수에 의해 변경 될 수 있 const 기능입니까?

StackOverflow https://stackoverflow.com/questions/105014

  •  01-07-2019
  •  | 
  •  

문제

얼마 전에 건너 왔어요 몇 가지는 코드로 표시된 구성원의 변수 등으로 mutable 키워드입니다.로 볼 수 있습니다 그것은 단순히 수정할 수 있습에서 변수 const 방법:

class Foo  
{  
private:  
    mutable bool done_;  
public:  
    void doSomething() const { ...; done_ = true; }  
};

이것만 이 키워드 또는 더 많은 것이 있는 그것은 눈에 보이는 것보다?내가 있기 때문에 이 방법을 사용한 클래스에서,마킹 boost::mutex 로 변경할 수 있도록 const 기능 안 위한 스레드 안전 상의 이유로,그러나,정직하게,그것은 느낌과 같습니다.

도움이 되었습니까?

해결책

그것은 차별화의 비트 const 및 논리적 const.논리적 const 는 개체의 경우에는 변경되지 않는 방식으로 표시를 통해 공용 인터페이스와 같은 잠그는 예입니다.다른 예로 들 수 있는 클래스 계산 값은 그것을 처음 요청을 캐시 결과입니다.

이후 c++11 mutable 에서 사용할 수 있는 람다를 나타내는 것에 의해 캡처 된 값을 수정할 수 있(그들은 기본적으로):

int x = 0;
auto f1 = [=]() mutable {x = 42;};  // OK
auto f2 = [=]()         {x = 42;};  // Error: a by-value capture cannot be modified in a non-mutable lambda

다른 팁

mutable 키워드는 방법은 피어스 const 베를 드레이프를 통해 귀하의 개체입니다.이 있는 경우 const 참조 또는 포인터를 객체,수정할 수 없는 객체에는 어떤 방법 를 제외하고 언제 어떻게 표시 mutable.

const 참조 또는 포인터 당신에 제약:

  • 만 읽기에 대한 액세스는 모든 볼 수 있는 데이터 구성원
  • 는 권한을만 호출하는 방법으로 표시 const.

mutable 예외 그래서 그것을 작성할 수 있습 또는 설정 데이터로 표시되어 있는 멤버 mutable.는 외부에서 볼 수 있는 차이입니다.

내부적으로 그 const 는 방법을 볼 수 있을 작성할 수도 있습을 데이터로 표시되어 있는 멤버 mutable.기본적으로 const 베가 너였구나 종합적으로.그것은 완전히 API 디자이너는지 확인 mutable 지 않을 파괴 const 개념과 이에 사용되는 유용한 특별한 경우.이 mutable 키워드는 데 도움이기 때문에 명확하게 표시 데이터 구성원이 적용되는 이러한 특별한 경우.

에서 연습할 수 있습 사용 const 집안의 코드 베이스(당신이 본질적으로 원하는"감염의"codebase 과 const "병").이 세상에서 포인터를 참조 const 매우 몇 가지 예외를 제외하고,열매를 산출하는 코드가 이해하기 쉽고 이해할 수 있습니다.에 대한 흥미로운 여담보"참조 투명성".

이 없 mutable 키워드 당신은 결국 사용하도록 강요됩 const_cast 을 처리하는 여러 가지 유용한 특별한 경우 그것은(캐싱,ref 계산,디버깅,데이터,etc.).불행하게도 const_cast 은 훨씬 더 많은 파괴적인보 mutable 기 때문에 그것은 강제 API 클라이언트 파괴 const 보호의 객체(s)그 사용하고 있습니다.또한 그것이 원인을 널리 const 파괴: const_casting const 포인터 또는 참조용에 자유롭게 작성하고 메소드를 호출하 액세스를 볼 수 있 회원입니다.달 mutable 필요 API 디자이너 운동하기 위한 실제적인 표준 const 예외,일반적으로 이러한 예외에 숨겨진 const 방법 운영에 개인 데이터입니다.

(N.B.을 참조하여 데이터와 방법 가시성 몇 번입니다.나는 이야기에 대해 구성원으로 표시 공용 대전용 또는 보호는 완전히 다른 유형의 개체 보호 설명 .)

귀하의 사용으로 부스트::mutex 는 정확히 무엇을 이 키워드를 위한 것입니다.다른 사용에 대한 내부 결과를 캐싱하는 속도 액세스입니다.

기본적으로,'변경 가능한'에 적용되는 모든 클래스 특성에 영향을 미치지 않는 외부에 표시되는 상태의 개체입니다.

에서 샘플 코드에 당신의 질문을 변경할 수 있 부적절한 경우의 값 done_ 영향을 미치는 외부 상태이며,이에 따라 달라집니다.;부분입니다.

변경 가능한 표시를 위한 특정 특성을 수정할 수 있는 내에서 const 방법이 있습니다.는 유일한 목적이다.신중하게 생각하기 전에 그것을 사용하기 때문에,당신의 코드는 것이 더 선명하게 표시되고 읽기 쉽을 변경하는 경우 디자인 보다는 오히려 사용 mutable.

http://www.highprogrammer.com/alan/rants/mutable.html

그래서 위의 경우 광기 없 변경은,그것이 무엇입니까?기 이 미묘한 경우:변경 가능한가에 대해 는 경우 객체를 논리적으로 일정이지만,실제 필요 변경합니다.이러한 경우는 몇과 사이지만,그들이 존재합니다.

예 저에게 포함 캐시 및 임시 디버깅 변수입니다.

이용 상황에서 당신은 숨겨져 내부 상태로 캐시입니다.예를 들어:

class HashTable
{
...
public:
    string lookup(string key) const
    {
        if(key == lastKey)
            return lastValue;

        string value = lookupInternal(key);

        lastKey = key;
        lastValue = value;

        return value;
    }

private:
    mutable string lastKey, lastValue;
};

그리고 당신은 수 있다 const HashTable 체 여전히 사용 lookup() 방법,수정하는 내부 캐시입니다.

그래,그건 그것이 무엇입니다.나는 사용을 위해 회원들에 의해 변경되는 방법하지 않는 논리적으로 변경은 상태의 클래스의 인스턴스에 대한 속도를 조회 구현을 통해 캐시:

class CIniWrapper
{
public:
   CIniWrapper(LPCTSTR szIniFile);

   // non-const: logically modifies the state of the object
   void SetValue(LPCTSTR szName, LPCTSTR szValue);

   // const: does not logically change the object
   LPCTSTR GetValue(LPCTSTR szName, LPCTSTR szDefaultValue) const;

   // ...

private:
   // cache, avoids going to disk when a named value is retrieved multiple times
   // does not logically change the public interface, so declared mutable
   // so that it can be used by the const GetValue() method
   mutable std::map<string, string> m_mapNameToValue;
};

지금 사용해야 합니다 이것으로 관리-concurrency 문제에 큰 관심으로,발신자는 가정할 수 있는 그들은 스레드에 안전한 사용하는 경우에만 사용 const 방법이 있습니다.그리고 물론,수정 mutable 데이터 변경하지 않아야 합체의 행동에 어떤 중요한 패션,무언가가 될 수 있는 위반에 의해 예을 했을 경우,예를 들어,그것은 것으로 예상되었을 변경하는 디스크에 기록된 것 즉시 표시됩니다.

mutable 존재하지 않으로 추측하도록 허용을 수정하는 데이터에서는 그렇지 않으면 일정한 기능입니다.

의도가 있을 수 있는 함수는"아무것도하지 않는"내부 상태의 개체,그래서 당신은 마크 기능 const, 지만,당신은 수도 정말 필요한 수정의 일부 개체 상태 방법으로 영향을 미치지 않고 올바른 기능이 있습니다.

키워드 역할을 수 있습에 대한 힌트를 컴파일러--이론 컴파일러 배치할 수 있는 일정한 물건(글로벌)에서 메모리는 읽기 전용으로 표시되어 있습니다.의 존재 mutable 힌트는 이야 하지 않을 수행 할 수 있습니다.

여기에 몇 가지 유효한 이유를 선언하고 사용하는 변경 데이터:

  • 스레드에 안전합니다.선언 mutable boost::mutex 완벽하게 적당합니다.
  • 통계입니다.의 수를 계산 통화 기능을 제공,일부 또는 전부의 그것의 인수입니다.
  • 메모이 제이션.컴퓨팅 비싼 대답하고,다음 그것을 저장하는 향후 참조를 위해 보다는 오히려 다시 계산습니다.

변경 가능한 경우에 사용 변수가 내부에는 클래스가 유일 이내에 사용하는 등 신호를 같은 것들에 대한 예 mutex 또는 잠급니다.이 변수는 변하지 않는 행동을 의지하기 위해 필요한 구현하는 스레드에 안전 클래스의 자체입니다.따라서이없는 경우"변경",당신이 할 수 없을 것이 있다"const"기능 때문에 이 변수를 변경해야에서는 모든 기능 사용할 수 있습니다.따라서,변경할 수 있었을 도입하여 구성원이 변수로 쓰기도 const 기능입니다.

변경할 수 있는 지정한 알려 모두 컴파일러 그리고 리더는 그것 안전하고 예상되는 멤버변수는 수정될 수 있습에 const 회원 기능입니다.

변경에 주로 사용되는 세부사항을 구현합니다.사용자는 클래스의 할 필요가 없이 그것에 대해 알고,따라서는 방법의 그가 생각해야한다""수 const 이 될 수 있습니다.귀하의의 예로는 mutex 변경할 수는 좋은 정식 예입니다.

그것의 사용하지 않는 해킹,하지만 다음과 같은 많은 것들 C++에서 변경 가능 야에 대한 해킹으로 가고 싶어하지 않는 모든 방법으로 다시 뭔가를 표시하지 않아야 const non-const.

사용하"변경 가능한 때"한 것은 논리적으로 무국적자는 사용자(고 이렇게 해야"const"getters 공공 장소에서 클래스'Api)지 않는 무국적 기본 구현은(코드입니다.cpp).

는 경우 사용 가장 많은 게으른 초기화 상태-"작은 보통 오래된 데이터는"회원입니다.즉,그것은 이상적인에 좁은 경우 이러한 회원은 비용을 작성(프로세서)또는 주변(메모리)고 많은 사용자의 개체의 적이 그들을 부탁드립니다.그 상황에서 당신이 원하는 게으른 건설에 대한 성능을,이후의 90%는 객체를 구축 필요하지 않습니다 그들을 구축하 모두에서,아직 당신은 여전히 필요가 존재하는 올바른 무국적자에 대한 API 를 공개 소비입니다.

변경 가능한 변경 사항의 의미 const 에서 비트 const 을 논리적 const 위해 클래스입니다.

즉,클래스로 변경 가능한 구성원은 더 이상 비트 const 과에 더 이상 나타나지 않습니다 읽기만 섹션의 성능을 크게 향상시킵니다.

또한,수정하는 유형을 확인하여 허용 const 회원 기능을 변경 변경 가능한 구성원 사용하지 않고 const_cast.

class Logical {
    mutable int var;

public:
    Logical(): var(0) {}
    void set(int x) const { var = x; }
};

class Bitwise {
    int var;

public:
    Bitwise(): var(0) {}
    void set(int x) const {
        const_cast<Bitwise*>(this)->var = x;
    }
};

const Logical logical; // Not put in read-only.
const Bitwise bitwise; // Likely put in read-only.

int main(void)
{
    logical.set(5); // Well defined.
    bitwise.set(5); // Undefined.
}

다른 답변에 대한 더 많은 정보만을 강조하는 것 그것이 단지에 대한 유형-안전하고 그 영향을 미치는 컴파일된 결과입니다.

어떤 경우에(같은 가난하게 디자인되는 반복기)클래스를 유지해야 카운트 또는 기타 부수 값에 영향을 주지 않는 주요"상태"를 클래스입니다.이것은 대부분 내가 볼 수 있는 곳 변경 가능한 사용됩니다.없이 변경할 수,당신은 강을 희생하는 전체 const-의 디자인이다.

그것은 같은 느낌이킹의 대부분의 시간이 나에게뿐만 아니라.용에 매우 매우 몇 가지 상황입니다.

전형적인 예(에서 언급했듯이 다른 답변)와만 상황을 나는 보았 mutable 키워드에서 사용되는 지금까지에 대한 캐싱의 결과 복잡한 Get 방법,캐시로 구현되는 데이터의 구성원이 아니라 클래스로 정적 변수에서 방식(대한의 이유를 공유 사이의 여러 가지 기능 또는 일반 청결도).

일반적으로,대안을 사용하여 mutable 키워드은 일반적으로 정적 변수에 방법이나 const_cast 다.

또 다른 대한 자세한 설명서 .

마찬가지로 유연하고 상태를 유지할 수 있는 편리한 경우는 재정의 const 가상 기능을 수정하려면 아래 멤버변수는 함수입니다.대부분의 경우에 당신을 변경하려는 인터페이스의 기본 클래스,그래서 당신은 당신을 사용하여 변경 가능한 구성원의 변수다.

합 변경 가능한 키워드 할 때 매우 유용성 스텁스는 테스트 목적입니다.할 수 있습 stub const 기능 여을 증가시킬 수 있(변경 가능)카운터를 또는 어떤 테스트 기능을 추가한다.이 인터페이스의 스텁 클래스를 그대로 유지됩니다.

최고의 중 하나를 들어 우리가 사용하는 곳에 변경 가능한가에서 깊은 복사합니다.에서 복사본을 생성자리 const &obj 이 사용되고 있습니다.그래서 새로운 객체를 만든 것의 일정한 유형입니다.우리가 원하는 경우 변경(대부분이 우리가 변경되지 않는 드문 경우는 변경 될 수 있습니다)회원이 새롭게 만들어 const 개체 우리는 그것을 선언할 mutable.

mutable 스토리지 등에서만 사용할 수 있습니다 비 static 비 const 의 데이터 멤버 클래스입니다.변경 가능한 데이터 구성원의 클래스로 수정할 수 있는 경우에도 그 개체의 일부로 선언되 const.

class Test
{
public:
    Test(): x(1), y(1) {};
    mutable int x;
    int y;
};

int main()
{
    const Test object;
    object.x = 123;
    //object.y = 123;
    /* 
    * The above line if uncommented, will create compilation error.
    */   

    cout<< "X:"<< object.x << ", Y:" << object.y;
    return 0;
}

Output:-
X:123, Y:1

위의 예에서,우리가 값을 변경 할 수 있의 멤버변수 x 비록 그것의 일부 개체로 선언되 const.이 때문에 이 변수 x 선언으로 변경할 수 있습니다.그러나 당신이 시도하는 경우 수정하는 값의 멤버변수 y, 컴파일러에서는 오류가 발생합니다.

매우 키워드'변경 가능한'실제로 예약 키워드입니다.자주 사용하는 값을 변화의 일정한 변수가 있습니다.하려는 경우가 여러 값의 constsnt,키워드를 사용하여 변경할 수 있습니다.

//Prototype 
class tag_name{
                :
                :
                mutable var_name;
                :
                :
               };   
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top