self에 대한 non const 포인터를 통해 const 메소드 내에서 self 수정

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

  •  21-12-2019
  •  | 
  •  

문제

다음 예에서 const 객체는 다음을 통해 자신을 수정할 수 있습니다. const 그 방법에서는 다음을 통해 자체적으로 액세스하기 때문입니다. non-const 바늘.(ideone에 있는 동일한 프로그램)

#include <iostream>

struct Object;

Object * g_pObject;

struct Object
{
    Object():m_a(0){}

    void ModifySelfViaConstMethod() const
    {
        g_pObject->m_a = 37;
    }

    int m_a;
};

int main()
{
    Object o;
    g_pObject = &o;

    const Object & co = o;
    std::cout << co.m_a << "\n";
    co.ModifySelfViaConstMethod();
    std::cout << co.m_a << "\n";

    return 0;
}

저는 C++ 표준을 잘 읽지 못해서 여기에 질문합니다.

표준은 이에 대해 무엇을 말합니까?

ㅏ)const 메소드는 이와 같은 작업을 수행할 때 객체가 수정되지 않은 상태로 유지된다는 것을 보장하지 않습니다.

b) 잘 정의되어 있고 컴파일해야 합니까?

c) 다른?

도움이 되었습니까?

해결책

표준은 이에 대해 무엇을 말합니까?

(다른 표현으로) 이렇게 말해요 this 유형이 있음 const Object *, 를 통해 멤버를 직접 수정하거나 const가 아닌 멤버 함수를 호출할 수 없도록 합니다. this.함수가 액세스할 수 있는 전역 변수로 무엇을 할 수 있는지에 대해서는 아무 것도 언급하지 않습니다.함수가 호출되는 객체에 대한 직접 액세스만 제어합니다.

const 메소드는 이와 같은 작업을 수행할 때 객체가 수정되지 않은 상태로 유지된다는 것을 보장하지 않습니다.

아니요, 그렇지 않습니다.이는 함수가 객체를 수정하지 않는다는 의도를 명시하고 실수로 해당 의도를 위반하는 것에 대한 일부 보호 기능을 제공합니다.적절하게 미친 프로그래머가 사용하는 것을 막지는 않습니다. const_cast, 또는 (여기서와 같이) 전역 변수를 통한 제어되지 않은 결합으로 약속을 어길 수 있습니다.

잘 정의되어 있고 컴파일해야 합니까?

예. o 그 자체는 상수가 아니므로 상수가 아닌 포인터나 참조를 취하는 것을 막을 수 있는 방법은 없습니다.그만큼 const 멤버 함수에서는 다음을 통해서만 객체에 대한 액세스를 제한합니다. this, 다른 포인터를 통한 임의의 객체가 아닙니다.

다른 팁

당신이 선언할 때 const 기능적으로는 "자신의 이익을 위해"입니다.

즉, 당신은 그것을 선언 const 왜냐하면 초기 디자인에 따르면 런타임 중에 호출될 객체를 변경해서는 안 되기 때문입니다.

이 함수 구현의 후반부에서 객체를 변경하게 되면 컴파일러는 "당신에게 소리를 지르며" 그것이 틀렸다고 알립니다.

물론 컴파일러는 다음에 적용될 때만 그러한 시도를 식별할 수 있습니다. this.

주어진 예에서 컴파일러는 두 항목 간의 비교가 필요하기 때문에 문제를 식별할 수 없습니다. this 그리고 g_pObject, 이러한 비교는 런타임 중에만 발생할 수 있습니다.

메소드가 다음과 같이 선언된 경우 const, 컴파일러는 인스턴스가 가리키는 인스턴스를 확인합니다. this 포인터는 수정되지 않습니다.수정하려고 하면 this 예를 들어 컴파일러가 실패합니다.그러나 컴파일러는 이를 알 수 없습니다. g_pObject 그리고 this 실제로 동일한 인스턴스를 가리키고 있습니다.이를 위해서는 런타임 비교가 필요하며 컴파일러는 내부에서 사용되는 모든 포인터의 런타임 비교를 수행하는 데 시간을 낭비하지 않습니다. const 만약에 그들이 방법을 ~할 것 같다 일치하는 this 바늘.따라서 수정하려는 경우 Object 외부 포인터를 통해 직접 확인해야 합니다. 예:

void ModifySelfViaConstMethod() const
{
    if (g_pObject != this)
        g_pObject->m_a = 37;
}

C++의 일관성은 보안이 아닌 안전 도구입니다.

불변성을 존중하는 코드는 예상대로 작동할 가능성이 높으며, 불변성을 없애려는 의도하지 않은 모든 시도는 컴파일러에서 경고됩니다.

"내가 무엇을 하고 있는지 알고 있는 경우"에는 다음과 같은 다양한 도구를 찾을 수 있습니다. const_cast 운영자와 mutable 진부한 C 스타일 캐스트에 대한 키워드입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top