Item 3: Use const whenever possible

모르핀·2021년 4월 15일
0

C++기초

목록 보기
3/7

pointer와 const

const가 *의 왼쪽에 있으면 pointing value가 constant이고
const가 *의 오른쪽에 있으면 pointer 자체가 constant이다.

char greeting[] = "hello";
char* p1 = greeting;
const char *p2 = greeting;       //                   constant data
char* const p3 = greeting;       // constant pointer
const char* const p4 = greeting; // constant pointer, constant data
//2가지 모두 같은 의미
void f1(const Widget *p1);
void f2(Widget const *p1);
// ==을 =로 잘못 썼을 경우 에러가 발생하도록 만들어서 잘못 동작하는 경우를 미연에 방지
if(a * b = c) 
if(3 == numberOfAttack)

STL interator const

STL의 iterator는 T* 포인터처럼 비슷하게 동작하도록 만들어졌으며,
iterator 앞에 const를 붙이는 것은 T * const //constant pointer 처럼 동작하며,
const_iterator 자체를 쓰는 것은 const T * // constant pointing value 와 유사하게 동작한다.

const std::vector<int>::iterator iter = // iter acts like a T* const
vec.begin();
*iter = 10; // OK, changes what iter points to
++iter; // error! iter is const
std::vector<int>::const_iterator cIter = //cIter acts like a const T*
vec.begin();
*cIter = 10; // error! *cIter is const
++cIter; // fine, changes cIter

상수 멤버 함수(constant member function)

  1. 클래스의 인터페이스를 이해하기를 쉽게한다.(객체의 변경 가능 여부 확인 가능)

  2. const object를 사용하기 위해서 reference-to-const(효율을 높이기 위함)

void print(const TextBlock& ctb);
  1. const 키워드가 있고 없고의 차이로 오버로딩이 가능하다.
class TextBook
{
private:
    char text[10];
public:
    TextBook() : text("abcdefghi") {}
    
    const char& operator[](std::size_t position) const
    {
        return text[position];
    }

    char& operator[](std::size_t position)
    {
        return text[position];
    }
};

int main(void)
{
    TextBook tb;
    const TextBook ctb;

    cout << tb[0] << endl;   // non-constant
    tb[0] = 'x';             // non-constant
    cout << ctb[0] << endl;  // constant
    ctb[0] = 'x';            // constant error  
}

bitwise(physical) constness and logical constness

bitwise(physical) constness

member function에서 object의 어떠한 데이터도 변경이 일어나지 않는 것을 의미합니다.

logical constness

인터페이스상으로는 member function이 상수성을 가지고 있으나 내부적으로는 변수들이 바뀌는 것을 말합니다.

C++는 기본적으로 bitwise-constness를 제공합니다. 객체가 bitwise constness하다고 이야기한다면 그 객체의 어떠한 멤버도 정의된 후에는 변경이 일어나면 안됩니다.

하지만 다음 코드처럼 class의 field가 mutable인 경우 GetObjectID()함수는 const지만 field의 값이 변경되는 일이 일어납니다.

이러한 경우는 인터페이스상으로는 상수성이 유지되는 것처럼 보이지만 내부적으로는 field값이 바뀌므로 logical-constness를 따르고 있다고 합니다.

class MyObject
{
public:
    MyObject();  // constructor
    ~MyObject(); // destructor

    long GetObjectID() const;
    void SetObjectID(long lngID);

    long GetObjectLength() const;
    void SetObjectLength(long lngLength);

private:
    mutable long m_lngID;
    long m_lngLength;
};
long MyObject::GetObjectID() const
{
    m_lngID = 25;    // Allowed b/c the member mutable
    m_lngLength = 0; // ERROR!
    return m_lngID;  // Allowed!
}

Avoiding Duplication in const and Non-const Member Functions

const version의 memer functon을 재사용하여 non-const version의 member function을 정의할 수 있다.

const char& operator[](std::size_t position) const
{
    ... // do bounds checking
    ... // log access data
    ... // verify data integrity
    return text[position];
}
char& operator[](std::size_t position)
{
    return
        const_cast<char&>
        (                   // cast away const on
                            // op[]'s return type;
            static_cast<const TextBlock&>(*this) // add const to *this's type;
                [position] // call const version of op[]
        );
}

reference

http://writebettercode.org/2006/05/discussion-topic-1-logical-vs-bitwise.html

profile
플어머

0개의 댓글