`const`의 많은 마스크

불변성은 종종 많은 프로그래밍 언어에서 "모범 사례"로 간주됩니다. 코드 베이스에 원치 않는 부작용이 발생할 가능성을 줄여서 버그가 발생하기 쉽습니다.

이 "모범 사례"에 대한 증거로 variables in Rust are immutable by default . 변경 가능한 변수를 선언하려면 mut 키워드를 명시적으로 사용하는 번거로움을 겪어야 합니다.

상태와 변경 가능성에 대한 의존도로 잘 알려진 언어인 C++도 이 "모범 사례"에서 예외가 아닙니다. 다른 많은 언어와 마찬가지로 const 키워드는 상수 "변수"를 선언하는 데 사용됩니다. 그러나 const 키워드는 다른 언어처럼 간단하지 않습니다. C++에서는 상황에 따라 어떻게 사용되는지에 따라 많은 의미가 있습니다. 어찌보면 다중분할 성격과 유사하게 const 키워드는 가면을 많이 쓴다고 할 수 있다.

간단한 방법


const 키워드를 사용하는 가장 간단하고 가장 친숙하고 직관적인 방법은 상수를 선언하는 것입니다. 다른 많은 프로그래밍 언어와 마찬가지로 const로 선언된 변수(또는 함수 매개변수)는 재할당할 수 없습니다.

int main() {
  // Mutable variable
  int variable = 5;
  // Immutable constant
  const int constant = 10;

  // This is legal
  variable = 1;
  // Throws an error
  constant = 25;

  return 0;
}


클래스 필드



변수와 마찬가지로 클래스 필드도 상수로 선언할 수 있습니다. 이 클래스에서 인스턴스화된 모든 개체는 해당 속성을 변경할 수 없습니다.

#include <string>

class Dog {
  public:
    std::string name;
    const std::string breed;

    Dog(const std::string& dogName, const std::string& dogBreed)
      : name(dogName)
      , breed(dogBreed)
    { }
};

int main() {
  Dog presto("Presto", "Siberian Husky");

  // This is legal
  presto.name = "Not Presto";
  // Throws an error
  presto.breed = "Not a Husky";

  return 0;
}


수업 방법



클래스 메서드도 선언할 수 있습니다const. 그렇게 함으로써 클래스 메소드는 클래스의 필드를 절대로 변경하지 않을 것을 약속합니다.

#include <string>

class Dog {
  private:
    std::string name;
  public:
    Dog(const std::string& dogName) : name(dogName) { }

    // This is a `const` method because it does not
    // mutate any of the fields.
    std::string getName() const { return name; }

    // On the other hand, this setter method
    // can **not** be `const` because it
    // mutates/sets a field to a value.
    void setName(const std::string& newName) { name = newName; }
};


포인터


const 키워드는 포인터와 매우 혼동됩니다. 얼핏 보면 단순한 생각처럼 보입니다. 그러나 포인터에 const 키워드를 사용하면 정확히 무엇을 선언하는지const 의문이 생깁니다. 메모리 주소에 대한 실제 포인터입니까 아니면 메모리 주소의 역참조 값입니까? 이 딜레마에 대해 C++에는 선언할 항목을 지정하는 방법이 있습니다const.

int main() {
  int foo = 1;
  int bar = 2;
  int baz = 3;

  // Constant actual pointer
  int* const actualPointer = &foo;

  // Constant dereferenced value
  const int* dereferValue = &bar;

  // Constant pointer **and** dereferenced value
  const int* const both = &baz;

  return 0;
}


변수 선언을 거꾸로 읽으면 이러한 뉘앙스를 기억하는 데 큰 도움이 됩니다. This StackOverflow answer은 이를 매우 잘 요약하고 고급 예제와 연습을 제공합니다. 초보자와 베테랑 모두에게 이 답변은 C++로 작업하는 모든 사람이 반드시 읽어야 합니다.

결론


const 키워드는 불변성을 적용하기 위한 메커니즘 그 이상입니다. 원치 않는 부작용으로부터의 안전망 그 이상입니다. 개발자에게는 의도를 암시하는 주석입니다. 함수(또는 변수)가 작동하는 방식에 대한 암시적 문서입니다. 예를 들어, const getter 메소드는 const 제약 조건 하에서 불가능하기 때문에 어떤 식으로든 코드를 엉망으로 만들지 않을 것임을 개발자에게 보장합니다.

코드 기반 전체에 여러const 선언을 추가하는 것이 불필요하게 장황하다고 주장할 수 있습니다. 네, 그것은 유효한 주장이지만 암시적 문서화에 의해 제공되는 이점과 불변성의 안전성은 단순히 장황함의 단점보다 큽니다(적어도 저에게는). 게다가 합당한 이유로 "모범 사례"로 간주됩니다.

따라서 필요한 만큼 많은const 선언으로 코드 기반을 장식하십시오!

좋은 웹페이지 즐겨찾기