불변과 const의 차이점 ‘계약’에서 크게 다릅니다. 불변은이

나는 종종 용어를 본 적이 immutableconst같은 의미로 사용. 그러나 내 (작은) 경험에서 두 가지는 코드에서 만드는 ‘계약’에서 크게 다릅니다.

불변은이 객체 변경 되지 않을 것이라는 계약을합니다 (예 : Python 튜플, Java 문자열).

Const는이 변수 의 범위에서 수정되지 않을 것이라고 계약을 맺습니다 (예 : C / C ++ 키워드와 같이이 기간 동안 객체에 대해 다른 스레드가 수행 할 수있는 작업에 대한 약속은 없습니다).

언어가 단일 스레드 (PHP)이거나 선형 또는 고유 한 타이핑 시스템 (Clean, Mercury, ATS)을 가지고 있지 않는 한, 둘은 동일하지 않습니다.

먼저,이 두 개념에 대한 나의 이해가 정확합니까?

둘째, 차이가 있다면 왜 거의 독점적으로 상호 교환 적으로 사용됩니까?



답변

이 차이가 가장 중요한 C ++에 대해 이야기하겠습니다.

올바르게 알 수 있듯이 불변 은 객체가 생성 된 후에는 전혀 변경 될 수 없음을 의미합니다. 이 생성은 물론 런타임에 발생할 수 있습니다. 즉, const객체가 반드시 컴파일 타임 상수는 아닙니다. C ++에서 (1)과 (2) 또는 (3)이 충족되면 객체를 변경할 수 없습니다.

  1. 멤버 함수에 mutable의해 변경된 멤버가 선언되지 않았습니다.const

  2. 선언 const

  3. const멤버 함수는 멤버 를 변경하기 위해 자격 const_cast을 제거 하는 데 사용하지 않습니다.const

그러나 액세스 수정자를 고려할 수도 있습니다. 작업이 내부적으로 인스턴스를 변경하지만 퍼블릭 인터페이스를 통해 관찰 가능한 인스턴스의 상태에 영향을 미치지 않으면 객체는“논리적으로 불변”입니다.

따라서 C ++는 변경 불가능한 객체를 만드는 데 필요한 도구를 제공하지만 C ++의 모든 것과 마찬가지로 도구는 최소한으로 충분하며 실제로 사용하기 위해 부지런해야합니다. 인스턴스 상태는 반드시 인스턴스 멤버 변수에 국한되는 것은 아닙니다. C ++은 참조 투명성을 강화하는 방법을 제공하지 않기 때문에 전역 또는 클래스 상태도 포함 할 수 있습니다.

constC ++에는 참조와 포인터를 규정하는 또 다른 기능이 있습니다. const참조 비 참조 할 수 const개체. 객체가 non-으로 선언 된 경우에만 참조를 const_cast통해 객체를 변경하는 데 사용 하는 것이 합법적입니다 (일반적으로 필요하거나 권장되지 는 않음) .constconst

int        i = 4;         // Non-const object.
const int* p = &i;        // const pointer.

*const_cast<int*>(p) = 5; // Legal.

물론 const객체 를 변경하는 것은 정의되지 않은 동작입니다 .

const int  i = 4;         // const object.
const int* p = &i;        // const pointer.

*const_cast<int*>(p) = 5; // Illegal.


답변

키워드 “final”이 “const”를 나타내는 Java에 대해서는 다음을 고려하십시오.

final Person someone = new Person();

이것은 someone다른 Person 객체를 절대로 참조 할 수 없음을 의미 합니다. 그러나 여전히 추천 된 사람의 세부 정보를 변경할 수 있습니다. 예 :someone.setMonthlySalary(10000);

그러나 someone“Immutable”객체 인 경우 다음 중 하나에 해당합니다. (a) 이름이 지정된 메서드가 없습니다. setMonthlySalary
(b) setMonthlySalary를 호출하면 항상 다음과 같은 예외가 발생합니다.UnsupportedOperationException


답변

불변 개체는 생성 후 상태가 변경되지 않는 개체입니다. 예를 들어;

string prefix = "Pre";
string postfix = "Post";
string myComplexStr = prefix + postfix;

이 예제에서 myComplexStr 객체는 변경할 수 없지만 값이 계산되므로 일정하지 않습니다. 그리고 문자열이고 정적 길이 속성을 가지고 변경할 수 없으므로 변경할 수 없습니다.

Const 객체는 일반적으로 Pi, “USA”, “StackOverflow.com”, 포트 번호 등과 같이 값이 컴파일 전에 알려진 실제 상수를 식별하는 데 사용됩니다.

이러한 관점에서 Const는 값이 프로그램에 의해 계산되지 않기 때문에 변경 불가능한 객체와 다릅니다.

그러나 C ++에서 “const”키워드에 대해 이야기하고 있다면 “const”가 불변의 객체를 만드는 데 사용된다고 말할 수 있습니다.


답변

먼저,이 두 개념에 대한 나의 이해가 정확합니까?

예. 그러나 두 번째 질문은 이러한 차이점을 이해하지 못한다는 것을 보여줍니다.

둘째, 차이가 있다면 왜 거의 독점적으로 상호 교환 적으로 사용됩니까?

constC ++ 에서는 불변성이 아닌 액세스 수준 ( “읽기 전용”을 의미)에만 사용됩니다 . 액세스 자체가 데이터와 완전히 분리되어 있음을 의미합니다. 예를 들어 일부 데이터를 조작 한 다음 const 참조를 통해 노출 할 수 있습니다. 액세스는 읽기 전용이지만 모든 데이터가 변경 가능하므로 데이터 자체입니다.

const는 액세스 제한 만 보장하지만 불변성은 (예를 들어 D와 같이) 객체 수명의 어느 단계에서나 데이터를 변경할 수있는 방법을 암시하지 않습니다 .

이제 const 이외의 다른 방법으로 일부 데이터에 액세스 할 수 없도록하여 C ++에서 불변성을 시뮬레이트 할 수 있으며 데이터가 초기화 된 후 더 이상 건드리지 않도록해야합니다. 그러나 데이터를 불변으로 표시하면 D와 같은 언어가 제공하므로 강력한 보장은 아닙니다. 이 언어는 해당 데이터를 수정하는 작업을 전혀 수행 할 수 없도록하는 반면, C ++에서는 실제로 필요한 경우 const 캐스팅 및 변경을 통해 데이터를 변경할 수 있습니다.

결국, 동일한 보장을 전혀 제공하지 않기 때문에 전혀 동일 하지 않습니다.


답변

자바 스크립트의 핵심 단어를 말하기 constObject.freeze

const바인딩에variables 적용됩니다 . 변경 불가능한 바인딩을 작성하므로 새 값을 지정할 수 없습니다.

Object.freeze객체 값에서 작동합니다. 객체를 불변으로 만듭니다 . 즉, 속성을 변경할 수 없습니다.


답변

C ++에서는 동일합니다. const메모리에 객체가 있고 해당 메모리에 쓸 수있는 OS 권한이 있으면 객체 를 변경할 수 있습니다 .


답변

C, C ++ 및 관련 언어에서 const 객체와 참조 또는 상수 참조 객체에 대한 포인터 사이에는 차이가 있습니다.

상수 객체를 수정하려고하면 정의되지 않은 동작이 발생합니다. (당신은 할 수 시도 , 해당 주소를 복용 const가 아닌 포인터에 주소를 캐스팅 한 다음 const가 아닌 포인터가 객체를 수정하는 것을 이용하여, 예를 들어 일정한 객체를 수정).

반면에 상수 포인터 또는 참조는 컴파일러에게이 포인터 또는 참조를 사용하여 객체를 수정할 수 없음을 알려줍니다. 포인터 또는 참조를 캐스트하고 오브젝트를 수정하려고 시도 할 수 있습니다. 개체 자체가 일정하면 나쁜 일이 발생합니다. 객체가 실제로 일정하지 않은 경우 변경됩니다. 이것은 물론 코드 사용자를 혼란스럽게하고 버그를 일으킬 수 있습니다.

C에서 “Hello”와 같은 문자열 리터럴을 사용하는 경우 5 개의 문자와 후행 0 바이트는 실제로 일정하지만 상수가 아닌 포인터를 얻습니다. 비 const 포인터를 사용하여 객체를 변경하는 것은 매우 나쁜 생각입니다.

C에서는 “const limit”포인터를 가질 수 있습니다. 즉, 대상이 일시적으로 일정하다는 의미입니다. “const restrict”포인터가 범위 내에있는 동안 어떤 방법으로도 객체를 수정하면 정의되지 않은 동작이 발생합니다. 이 포인터를 통해 객체를 변경하지 못하게하는 const 포인터보다 강력합니다.