ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Effective C++...2
    일지 2022. 5. 30. 08:51

    포인터의 상수 처리

    포인터는 const를 어디에 붙이는지에 따라 포인터를 상수 처리할지, 데이터를 상수 처리할지 달라진다.


    char greeting[] = "Hello";

    char* p = greeting; // 비상수 포인터, 비상수 데이터

    const char* p = greeting; // 비상수 포인터, 상수 데이터

    char* const p = greeting; // 상수 포인터, 비상수 데이터

    const char* const p = greeting; // 상수 포인터, 상수 데이터


     

    ※ 값의 수정이 필요한 경우가 아니면 const를 붙여두면 추후 실수를 막을 수 있다.

     

     

    상수 함수의 오버로딩

    클래스의 함수는 상수 여부만으로 오버 로딩이 가능하다.


    class TextBlock {

    public:

        ...

        const char& operator[] (std::size_t position) const

        { return text[position]; }

        char& operator[] (std::size_t position)

        { return text[position]; }

    private:

        std::string text;

    }



    논리적 상수성

    함수 내부적으로 상수성이 지켜지지 않더라도 사용자 측에서 알아채지 못하면 상수로 인정한다는 개념이다.


    class CTextBlock {

    public:

        std::size_t length() const;

    private:

        char* pText;

        mutable std::size_t textLength; // mutable 선언으로 상수 처리를 회피한다.

        mutable bool lengthIsValid;

    }

     

    std::size_t CTextBlock::length() const

    {

        if (!lengthIsValid) {

            textLength = std::strlen(pText); // 상수 함수 내부에서 의미 있는 처리가 진행될 수 있다.

            lengthIsValid = true;

        }

        return textLength;

    }


    다만 mutable을 이용한 상수 함수를 생성하면 비상수 함수와 동일한 기능을 수행하는 중복이 발생할 수 있다.

    이때, 비상수 함수에서 상수 함수를 호출하는 식으로 처리하면 코드 중복을 막을 수 있다.

     


    char& operator[](std::size_t position)

    {

        return const_cast<char&> (

            static_cast<const TextBlock&>(*this)[position]; // 상수 버전 호출

        );

    }


     

    ※ 상수 함수에서 비상수 함수를 호출하는 것은 값을 바꿀 수 있는 위험이 있으므로 하면 안 된다.

     

    댓글

Designed by Tistory.