본문 바로가기
IT/c++

C++ const 객체 및 키워드

by 뉴코딩맨 2023. 8. 4.
C++은 널리 사용되는 강력한 프로그래밍 언어 중 하나로, 객체 지향 프로그래밍과 저수준 프로그래밍 모두를 지원합니다. C++에서 const 키워드는 중요한 개념 중 하나로, 객체의 불변성을 보장하는 데 사용됩니다. const 키워드를 사용하여 객체를 정의하거나 함수 및 클래스의 멤버로 선언하면 해당 객체나 멤버의 값이 변경되지 않도록 제한됩니다. 이로써 안정성과 예측 가능성을 향상시키며, 코드의 실수로 인한 오류를 방지할 수 있습니다.
 
이 글에서는 C++의 const 키워드와 const 객체에 대해 자세히 살펴보고, const 키워드의 활용 방법과 특징, 그리고 다른 프로그래밍 언어와의 차이점 등을 설명하겠습니다.

 

 

1. C++의 const 키워드

C++에서 const 키워드는 객체, 변수, 함수 매개변수, 함수 반환값, 멤버 함수 등을 정의할 때 사용됩니다. const로 선언된 객체는 변경할 수 없는 불변의 속성을 가지며, const로 선언된 함수는 해당 함수 내에서 객체의 값을 변경할 수 없습니다.
 
const 키워드는 다음과 같은 형태로 사용될 수 있습니다.

 

const int num = 10; // const 변수 선언 및 초기화
 
또는 함수 매개변수와 함수 반환값으로 사용될 수도 있습니다.
 
void PrintValue(const int value); // const 매개변수 사용
const int GetNumber(); // const 반환값 사용

 

2. C++ const 객체란?

C++에서 const 객체는 변경이 불가능한 객체를 의미합니다. const 키워드를 사용하여 객체를 선언하면, 해당 객체의 값을 변경하는 시도가 컴파일 단계에서 오류로 감지되어 변경이 제한됩니다. const 객체를 사용하면 프로그래머가 실수로 값의 변경을 방지하고, 안정성과 예측 가능성을 높일 수 있습니다.
 

3. const 멤버 함수

const 멤버 함수란 해당 멤버 함수가 const 객체 내에서 호출될 수 있음을 나타냅니다. const 멤버 함수는 해당 객체의 상태를 변경하지 않는 메서드입니다. 이러한 멤버 함수를 사용하여 const 객체의 내용을 읽을 수 있지만 수정할 수는 없습니다. 따라서 const 멤버 함수는 객체의 불변성을 보장하는 데 도움이 됩니다.
 

4. const와 불변성

const 객체는 불변성을 가집니다. 이는 객체가 생성되고 초기화된 이후에는 그 값을 변경할 수 없음을 의미합니다. C++에서 const 객체는 반드시 선언과 동시에 초기화되어야 하며, 이후에는 값을 변경하는 것이 불가능합니다. 따라서 const 객체는 안정성과 안전성을 보장하며, 예기치 않은 오류를 방지하는 데 도움이 됩니다.
 

5. const 객체의 선언과 초기화

const 객체는 선언과 동시에 반드시 초기화되어야 합니다. 예를 들어, 다음과 같이 선언과 동시에 초기화할 수 있습니다.

 

const int num = 10;

 

6. const 객체의 이점

C++에서 const 객체를 사용하는 이점은 다음과 같습니다:
  • 불변성 보장: const 객체는 생성된 이후에는 값을 변경할 수 없으므로 불변성을 보장합니다.
  • 안정성 확보: const 객체를 사용하면 의도하지 않은 값 변경으로 인한 예기치 않은 동작을 방지할 수 있습니다.
  • 컴파일러 최적화: const 객체는 변경이 불가능하므로 컴파일러가 최적화를 수행하여 성능을 향상시킬 수 있습니다.

 

 

7. const와 포인터

포인터를 const로 선언하면 해당 포인터가 가리키는 값을 변경할 수 없습니다. 즉, const 포인터는 변경되지 않는 포인터를 의미합니다. 포인터가 const로 선언되면 포인터가 가리키는 주소가 변경되지 않으며, 포인터가 가리키는 값 역시 변경될 수 없습니다.
 
const int* ptr = # // ptr은 num의 주소를 가리키는데, num의 값은 변경되지 않음
 
반면에 const 포인터는 포인터 자체가 변경되지 않는 포인터를 의미합니다. 즉, const 포인터는 다른 주소를 가리키도록 변경될 수 없습니다.
 
int* const ptr = # // ptr은 변경되지 않는 주소를 가리키며, 가리키는 값은 변경될 수 있음
 
또한 const 포인터와 const 데이터를 함께 사용하여 값을 보호할 수도 있습니다.

 

const int* const ptr = # // ptr과 num의 값 모두 변경되지 않음

 

8. const와 함수

함수를 const로 선언하면 해당 함수 내에서 객체의 값을 변경할 수 없습니다. 따라서 const 함수는 해당 함수가 호출된 객체의 불변성을 보장합니다. const 함수를 사용하여 객체의 값을 읽을 수 있지만, 객체의 상태를 변경하는 것은 불가능합니다.
 
class MyClass {
public:
    void DisplayValue() const {
        // 객체의 값을 읽을 수 있지만, 변경은 불가능
        cout << value << endl;
    }

private:
    int value;
};

 

9. const와 클래스

클래스에서 멤버 변수를 const로 선언하면 해당 멤버 변수의 값을 변경할 수 없습니다. 즉, 멤버 변수가 const로 선언되면 그 값은 생성자를 통해 초기화되고 이후에는 변경되지 않습니다.

 

class MyClass {
public:
    MyClass(int val) : value(val) {}

    void DisplayValue() const {
        // 멤버 변수 value는 const로 선언되어 값 변경 불가능
        cout << value << endl;
    }

private:
    const int value;
};

 

const로 선언된 멤버 변수는 클래스의 모든 멤버 함수에서 읽을 수 있지만, 변경할 수는 없습니다. 이로써 클래스의 불변성을 보장하고 안전성을 강화할 수 있습니다.
 

10. const와 상속

상속 관계에서도 const 키워드의 동작이 중요합니다. 기본 클래스에서 멤버 함수를 const로 선언하면 파생 클래스에서도 그 멤버 함수를 상속받을 때 const로 선언되어야 합니다.

 

class BaseClass {
public:
    void DisplayValue() const {
        // 기본 클래스의 const 멤버 함수
        cout << value << endl;
    }

private:
    int value;
};

class DerivedClass : public BaseClass {
public:
    // 파생 클래스에서도 const로 선언되어야 함
    void DisplayValue() const {
        // 기본 클래스의 const 멤버 함수를 오버라이딩
        BaseClass::DisplayValue();
    }
};
 
이렇게 상속 관계에서도 const 키워드를 올바르게 사용하면 객체의 불변성을 유지하고 의도하지 않은 값 변경으로 인한 오류를 방지할 수 있습니다.
 

11. const와 템플릿

템플릿을 사용하여 일반화된 코드를 작성할 때도 const 키워드를 활용할 수 있습니다. 템플릿 함수의 인자로 const 타입을 사용하면, 해당 함수가 호출될 때에도 인자의 값이 변경되지 않습니다.

 

template <typename T>
void PrintValue(const T& value) {
    // const 인자로 인해 값 변경 불가능
    cout << value << endl;
}
 
이렇게 템플릿을 사용할 때도 const를 적절히 활용하여 안정성과 예측 가능성을 확보할 수 있습니다.
 

12. C++ const와 다른 언어의 차이점

C++의 const는 다른 언어의 상수와 유사하지만, 일부 차이점이 있습니다. C++의 const는 런타임 상수가 아닌 컴파일 타임 상수로서, 컴파일러에 의해 상수 값이 결정됩니다. 이는 C++ 컴파일러가 최적화를 수행하여 성능을 향상시키는 데 도움이 됩니다.
 
또한, C++의 const는 포인터와 함께 사용할 때 특별한 의미를 갖습니다. const 포인터는 포인터 자체 또는 포인터가 가리키는 값을 변경하지 않음을 의미하며, 포인터가 가리키는 값이 변경되지 않는 const 포인터도 존재합니다.
 
이러한 차이점은 C++에서 const의 활용에 유용하며, 다른 언어와의 호환성을 유지하면서 안정성과 성능을 보장할 수 있습니다.
 

13. C++ const의 활용

C++의 const는 다양한 상황에서 활용될 수 있습니다. 주로 다음과 같은 경우에 사용됩니다.
 
  • 불변성 보장: const를 사용하여 객체, 변수, 함수 매개변수, 함수 반환값 등을 정의하면 값의 변경을 방지하여 불변성을 보장합니다.
  • 안정성 강화: const를 사용하여 실수로 값의 변경을 방지하고, 의도하지 않은 동작을 예방하여 코드의 안정성을 높일 수 있습니다.
  • 템플릿 사용: const를 템플릿과 함께 사용하여 일반화된 코드를 작성하면, 컴파일 타임 상수로서 최적화된 코드를 구성할 수 있습니다.
  • 클래스 설계: const를 멤버 변수, 멤버 함수, 클래스 상속 등에 활용하여 객체의 불변성을 강화하고 안전한 클래스 설계를 도모할 수 있습니다.

14. C++ const의 성능 최적화

C++의 const는 컴파일 타임 상수로서 컴파일러에 의해 최적화될 수 있습니다. const로 선언된 객체나 변수는 변경이 불가능하므로, 컴파일러는 해당 객체나 변수를 상수로 취급하여 최적화할 수 있습니다. 이로써 코드의 실행 속도가 향상되고 메모리 사용이 최적화됩니다.
 
C++ 컴파일러는 const로 선언된 객체를 인라인화하여 함수 호출을 최소화하고, 상수 값을 직접 대입하여 불필요한 메모리 접근을 방지합니다. 따라서 C++의 const를 적절히 활용하면 성능을 향상시키는 데 도움이 됩니다.
 

15. 결론

C++의 const는 객체의 불변성을 보장하고 안정성을 강화하는 데 중요한 역할을 합니다. const 키워드를 활용하여 객체, 변수, 함수, 클래스 등을 정의하면 코드의 예측 가능성이 높아지고, 런타임 오류를 방지할 수 있습니다. 또한, const를 템플릿과 함께 사용하여 최적화된 코드를 작성하면 성능을 향상시키는 데 도움이 됩니다.
 
C++ 개발자들은 const의 활용을 통해 안정성과 성능을 높이며, 높은 품질의 소프트웨어를 개발할 수 있습니다.
 

16. 출처

댓글