답변:
몇 가지 용도를 모 으려고합니다.
수명을 연장하기 위해 일부를 참조에 고정으로 바인딩합니다. 참조는 기본이 될 수 있으며 소멸자는 가상 일 필요는 없습니다. 올바른 소멸자는 여전히 다음과 같이 불립니다.
ScopeGuard const& guard = MakeGuard(&cleanUpFunction);
코드를 사용한 설명 :
struct ScopeGuard {
~ScopeGuard() { } // not virtual
};
template<typename T> struct Derived : ScopeGuard {
T t;
Derived(T t):t(t) { }
~Derived() {
t(); // call function
}
};
template<typename T> Derived<T> MakeGuard(T t) { return Derived<T>(t); }
이 트릭은 Alexandrescu의 ScopeGuard 유틸리티 클래스에서 사용됩니다. 임시가 범위를 벗어나면 Derived의 소멸자가 올바르게 호출됩니다. 위의 코드는 작은 세부 사항을 그리워하지만 큰 문제입니다.
const를 사용하여 다른 메소드가이 오브젝트의 논리적 상태를 변경하지 않도록하십시오.
struct SmartPtr {
int getCopies() const { return mCopiesMade; }
};
copy-on-write 클래스에 const를 사용 하여 컴파일러 가 복사 할시기와 시기를 결정할 수 있도록합니다.
struct MyString {
char * getData() { /* copy: caller might write */ return mData; }
char const* getData() const { return mData; }
};
설명 : 원본과 사본의 데이터가 동일하게 유지되는 한 무언가를 복사 할 때 데이터를 공유 할 수 있습니다. 개체 중 하나가 데이터를 변경하면 이제 원본과 복사본의 두 가지 버전이 필요합니다. 즉,이다 복사 A의 쓰기 그들은 지금 모두 자신의 버전이 너무 어느 객체.
코드 사용 :
int main() {
string const a = "1234";
string const b = a;
// outputs the same address for COW strings
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
위의 스 니펫은 사용 된 C ++ 라이브러리가 copy-on-write를 구현하기 때문에 GCC에 동일한 주소를 인쇄합니다 std::string
. 두 문자열은 별개의 객체이지만 문자열 데이터에 대해 동일한 메모리를 공유합니다. b
비 콘스탄트를 만드는 것은 비 콘스탄트 버전을 선호 operator[]
하고 GCC는 백업 메모리 버퍼의 사본을 생성합니다. 우리는이를 변경할 수 있고 데이터에 영향을 미치지 않아야합니다 a
!
int main() {
string const a = "1234";
string b = a;
// outputs different addresses!
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
복사 생성자가 const 객체와 임시에서 복사를 수행하려면 다음을 수행하십시오 .
struct MyClass {
MyClass(MyClass const& that) { /* make copy of that */ }
};
사소하게 변경할 수없는 상수를 만들기 위해
double const PI = 3.1415;
값이 아닌 참조를 통해 임의의 객체를 전달하는 경우 - 값 이 비싸거나 불가능한 값을 전달하지 않도록
void PrintIt(Object const& obj) {
// ...
}
C ++에는 const의 두 가지 주요 용도가 있습니다.
상수 값
값이 수명 동안 변경되지 않거나 변경되지 않아야하는 변수, 멤버 또는 매개 변수의 형식 인 경우 const로 표시해야합니다. 이것은 객체의 돌연변이를 방지하는 데 도움이됩니다. 예를 들어 다음 함수에서 전달 된 Student 인스턴스를 변경할 필요가 없으므로 const로 표시합니다.
void PrintStudent(const Student& student) {
cout << student.GetName();
}
왜 당신이 이것을 할 것입니다. 기본 데이터를 변경할 수 없다는 것을 알고 있으면 알고리즘에 대해 추론하기가 훨씬 쉽습니다. "const"는 도움이되지만 이것이 달성 될 것이라고 보장하지는 않습니다.
분명히, cout으로 데이터를 인쇄하는 데는 많은 생각이 필요하지 않습니다. :)
멤버 메소드를 const로 표시
이전 예제에서 Student를 const로 표시했습니다. 그러나 C ++은 학생에서 GetName () 메소드를 호출하면 객체가 변경되지 않는다는 것을 어떻게 알았습니까? 그 대답은 그 방법이 const로 표시되었다는 것입니다.
class Student {
public:
string GetName() const { ... }
};
메소드를 "const"로 표시하면 두 가지 작업이 수행됩니다. 주로 C ++ 에이 방법으로 객체를 변경하지 않는다고 알려줍니다. 두 번째는 모든 멤버 변수가 마치 const로 표시된 것처럼 취급된다는 것입니다. 이것은 클래스의 인스턴스를 수정하는 데 도움이되지만 막지는 않습니다.
이것은 매우 간단한 예이지만 질문에 대답하는 데 도움이되기를 바랍니다.
이 4 가지 선언의 차이점을 이해하도록주의하십시오.
다음 두 선언은 의미 상 동일합니다. 당신은 변경할 수 있습니다 곳 CCP1 및 CCP2 점을,하지만 당신은 그들이 가리키는있는 일을 변경할 수 없습니다.
const char* ccp1;
char const* ccp2;
다음으로 포인터는 const이므로 의미가 있으려면 무언가를 가리 키도록 초기화해야합니다. 다른 것을 가리킬 수는 없지만 가리키는 것은 바꿀 수 있습니다.
char* const cpc = &something_possibly_not_const;
마지막으로, 우리는 두 가지를 결합하여 가리키는 대상을 수정할 수 없으며 포인터가 다른 곳을 가리킬 수 없습니다.
const char* const ccpc = &const_obj;
시계 방향의 나선 규칙은 선언을 풀도록 도와줍니다 http://c-faq.com/decl/spiral.anderson.html