ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [const_cast] 제한적으로 활용하자
    개발/C·C++ 2021. 4. 27. 16:33

    출처 cppreference

     

    const_cast는 객체(변수)의 상수성을 없애주는 연산자입니다. 안정성 관점에서 없던 상수성이 생기는 건 괜찮지만 있던 상수성이 사라지는 건 위험합니다. 상수성을 부여해서 객체를 만든 이유가 있을 것이기 때문입니다. 그래서 const_cast는 정말 쓰지 않으면 안 되는 곳에, 고심해보고 사용해야 합니다. 다음은 연산자를 오버로딩해서 사용할 때 중복 코드를 방지하면서 코드 길이를 줄이는 과정에 const_cast가 사용되는 케이스입니다.

    class String
    {
    private:
        char* _chars;
       
    public:
        String(const char* chars)
        : _chars(new char[strlen(chars) + 1]
        {
            strcpy(_chars, chars);
        }
        
        char& operator[](int index)
        {
            return _chars[index];
        }
        
        ~String()
        {
            delete[] _chars;
        }
    }
    
    int main()
    {
        String str0("kim");
        cout << str0[0] << endl;
    }

    일반 객체를 선언해서 사용할 때는 문제가 딱히 문제될 것이 없습니다. 상황에 따라서 객체에 상수성을 부여해야 상황이 생길 수 있습니다. 예제에서는 객체를 const를 만들면 인덱스 연산자([])를 사용할 수 없습니다. const 객체는 const 함수만 호출할 수 있기 때문입니다. 따라서 const 함수를 따로 정의해줘야 합니다. 예제에서는 함수 본문이 한 줄밖에 되지 않으므로 본문을 복사 붙여넣기 해도 됩니다만, 정의부가 긴 함수를 그대로 복사 붙여넣는 것은 효율적이지 못합니다. 이 때 const_cast를 활용할 수 있습니다.

    class String
    {
    private:
        char* _chars;
       
    public:
        String(const char* chars)
        : _chars(new char[strlen(chars) + 1]
        {
            strcpy(_chars, chars);
        }
        
        char& operator[](int index)
        {
        	const String& str = *this;
            const char& ch = str[index];
            return const_cast<char&>(ch);
        }
        
        // 리턴에도 const를 붙여야 반환값을 수정할 수 없게 된다
        const char& operator[](int index) const
        {
            return _chars[index];
        }
        
        ~String()
        {
            delete[] _chars;
        }
    }
    
    int main()
    {
        String str0("kim");
        cout << str0[0] << endl;
        
        const String str1("kim");
        cout << str[1] << endl;
    }

    일반 함수는 자기 자신에게 상수성을 부여하고, 그 객체에서 상수성 함수를 호출한 뒤에 리턴값에 상수성을 없앴습니다. 이 코드는 필요에 의해 일반 객체에 임시적으로 상수성을 부여했다가 반환 타입에 맞게 상수성을 제거한 것이므로 문제가 없습니다. 코드 중복 문제도 해결됩니다.

    댓글

Designed by Tistory.