답변:
const
키워드를 메소드에 추가하면 this
포인터는 기본적으로 const
객체에 대한 포인터가 되므로 멤버 데이터를 변경할 수 없습니다. (를 사용하지 않으면 mutable
나중에 자세히 설명).
const
키워드는 두 개의 유사한 방법, 객체 인 경우라고 하나 구현할 수 있다는 것을 의미 기능 서명의 일부 const
, 그리고 하나를.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
출력됩니다
Foo
Foo const
비 const 메소드에서는 const
버전 에서 할 수없는 인스턴스 멤버를 변경할 수 있습니다 . 위의 예제에서 메소드 선언을 아래 코드로 변경하면 약간의 오류가 발생합니다.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
멤버를 표시 할 수 mutable
있고 const
메서드를 변경할 수 있기 때문에 이는 사실이 아닙니다 . 내부 카운터 및 물건에 주로 사용됩니다. 그 해결책은 아래 코드입니다.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
어떤 출력
Foo
Foo const
Foo has been invoked 2 times
const는 메소드가 클래스의 멤버를 변경하지 않을 것을 약속합니다. 객체 자체가 표시된 경우에도 그렇게 표시된 객체의 멤버를 실행할 수 있습니다 const
.
const foobar fb;
fb.foo();
합법적 일 것입니다.
참조 얼마나 많은 및 C에서 "CONST"++의 사용은 있습니까? 자세한 내용은.
const
규정 수단이 방법은 임의의 값으로 호출 될 수있다 foobar
. const 객체에서 비 const 메소드를 호출 할 때 차이점이 있습니다. foobar
유형에 다음과 같은 추가 메소드 선언이 있는지 고려하십시오 .
class foobar {
...
const char* bar();
}
이 방법 bar()
은 상수가 아니며 상수가 아닌 값에서만 액세스 할 수 있습니다.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
그러나 아이디어 const
는 클래스의 내부 상태를 변경하지 않는 메소드를 표시하는 것입니다. 이것은 강력한 개념이지만 실제로 C ++에서는 적용 할 수 없습니다. 그것은 보증보다 더 약속입니다. 그리고 종종 부서지고 쉽게 부서지는 것.
foobar& fbNonConst = const_cast<foobar&>(fb1);
const
하지만 뒤에 아이디어 는 클래스의 내부 상태를 변경하지 않는 메소드를 표시하는 것입니다." 그것이 내가 찾던 것입니다.
const
? 로 표시되어야 함을 의미합니다 .
이러한 const는 'with const'메소드가 내부 데이터를 변경하면 컴파일러가 오류를 발생시킵니다.
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
시험
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
자세한 내용은 이것을 읽으십시오
C ++ 에서 Const 멤버 함수의 의미 상식 : 필수 중급 프로그래밍 은 다음과 같은 명확한 설명을 제공합니다.
X 클래스의 비 const 멤버 함수에서 this 포인터의 유형은 X * const입니다. 즉, 상수가 아닌 X에 대한 상수 포인터입니다 (const 포인터 및 Const에 대한 포인터 [7, 21] 참조). 이것이 참조하는 객체는 const가 아니기 때문에 수정할 수 있습니다. 클래스 X의 const 멤버 함수에서이 유형은 const X * const입니다. 즉, 상수 X에 대한 상수 포인터입니다.이 개체가 참조하는 개체가 const이므로 수정할 수 없습니다. const와 non-const 멤버 함수의 차이점입니다.
따라서 코드에서 :
class foobar
{
public:
operator int () const;
const char* foo() const;
};
다음과 같이 생각할 수 있습니다.
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
this
아닙니다 const
. 그것이 수정 될 수없는 이유는 그것이 prvalue이기 때문입니다.
다음 사항을 추가하고 싶습니다.
또한 만들 수 있습니다 그것을 const &
및const &&
그래서,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
답변을 자유롭게 개선하십시오. 나는 전문가가 아니다
*this
멤버 함수가 rvalue-ref-qualified이고 rvalue에서 호출 되더라도 항상 lvalue입니다. 예 .
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
"
const
멤버 기능" 이란 무엇입니까 ?객체를 검사하지 않고 검사하는 멤버 함수입니다.
const
멤버 함수는로 표시된다const
바로 멤버 함수의 파라미터리스트 후에 접미사. A의 멤버 함수const
접미사 "const 멤버 함수"또는라고 "검사."const
접미사가 없는 멤버 함수를 "비 const 멤버 함수"또는 "돌연변이 자"라고합니다.class Fred { public: void inspect() const; // This member promises NOT to change *this void mutate(); // This member function might change *this }; void userCode(Fred& changeable, const Fred& unchangeable) { changeable.inspect(); // Okay: doesn't change a changeable object changeable.mutate(); // Okay: changes a changeable object unchangeable.inspect(); // Okay: doesn't change an unchangeable object unchangeable.mutate(); // ERROR: attempt to change unchangeable object }
호출 시도
unchangeable.mutate()
는 컴파일시 오류가 발생했습니다. 에 대한 런타임 공간이나 속도 불이익이 없으며 런타임시const
이를 확인하기 위해 테스트 사례를 작성할 필요가 없습니다.후행
const
에inspect()
멤버 함수는 객체의 변경되지 않습니다 방법을 의미하는 것으로 사용되어야한다 추상 (클라이언트 표시) 상태를. 이는 메소드가 객체 구조체의 "원시 비트"를 변경하지 않는다고 말하는 것과는 약간 다릅니다. C ++ 컴파일러는 일반적으로 해결할 수없는 앨리어싱 문제를 해결할 수없는 경우 (즉, 객체의 상태를 수정할 수있는 불변의 별칭이 존재할 수있는 경우) "비트 단위"해석을 수행 할 수 없습니다. 이 앨리어싱 문제에 대한 또 다른 (중요한) 통찰력 : 포인터를 대상으로하는 객체를 가리켜도 객체가 변경되지 않는다는 보장은 없습니다. 단지 포인터를 통해 객체가 변경되지 않을 것이라고 약속합니다 .