LastMod:

👨‍💻 개인 공부 기록용 블로그 입니다.
💡 틀린 내용이나 오타는 댓글, 메일로 제보해주시면 감사하겠습니다!! (__)

42 Cursus - Cpp Module을 진행하기 위해 정리했었던 C++98 기본 개념들로, C++11, C++14와 다른 내용이 있을 수 있습니다.
각 개념은 정리한 시간 순으로 배치되어 있으며, 한 포스트에 배치된 개념이 크게 관련이 없을 수 있습니다.

명시적 형 변환 (Explicit Type Conversion)

  • C에서는 명시적 형 변환으로 한 가지 타입만을 제공하고, 이것이 상당히 강력하여 거의 무조건적으로 실행되기 때문에, 컴파일러가 이를 잡지 않아서 의도치 않은 오류를 발생시킬 수 있었다.
  • C++에서는 4가지의 타입 캐스트 연산자를 제공한다.
  • const_cast<new_type>( ) : 포인터나 레퍼런스의 상수성(constness)를 잠깐 제거해주는데에 사용한다.
    • 다른 형태의 형변환은 불가하며, 오직 상수성을 제거하는 데에만 사용이 가능하다.
    • 함수 포인터는 사용이 불가능하다.
  • static_cast<new_type>( ) : 논리적으로 변환 가능한 타입을 변환한다.
    • 컴파일 타임에 형변환에 대한 타입 오류를 잡아준다.
    • 실수↔정수, 열거형↔정수, 실수↔실수 등 다양한 변환을 허용하며, 배열→포인터, 함수→함수 포인터로 변경 가능하지만, 포인터를 다른 타입으로 변환하는 것은 허용하지 않는다.
    • 상속 관계에 있는 포인터 끼리는 변환이 가능하지만, downcast(부모→자식 형변환) 시에는 unsafe하게 동작할 수 있다.
  • dynamic_cast<new_type>( ) : safe downcast 에 사용된다.
    • 부모 클래스의 포인터에서 자식 클래스의 포인터로 다운 캐스팅 해주는 연산자이다. 부모 클래스의 포인터가 실제 무엇을 가리키고 있는지가 중요하다.
    • 런타임에 해당 타입이 다운 캐스팅이 가능한지 검사하기 때문에, 비용이 높다.
    • 포인터 타입으로 다운 캐스팅을 시도할 경우, 실패하면 nullptr을 반환한다.
    • 레퍼런스 타입으로 다운 캐스팅을 시도할 경우, 실패하면 std::bad_cast 에외를 발생시킨다.
  • reinterpret_cast<new_type>( ) : 임의의 포인터 타입끼리 변환을 허용한다.
    • 정수를 포인터로 바꿀 수도 있다. (이때, 정수값이 포인터의 절대 주소로 들어가기 되므로 위험하다.)
    • 결과 값을 잘못 사용하는 경우에는, 컴파일러 마다 동작이 다를 수 있고 예상치 못한 결과가 나올 수 있다.
  • C 스타일의 형변환을 만나면, C++ 컴파일러는 다음과 같은 순서로 형 변환을 시도한다.
    1. const_cast<new_type>(expr);
    2. static_cast<new_type>(expr):
    3. const_caststatic_cast
    4. reinterpret_cast<new_type>(expr);
    5. const_castreinterpret_cast

객체 (Object)와 클래스 (Class)

  • 객체(Object)는 클래스에서 정의한 것을 토대로 메모리에 실제로 할당된 것(클래스의 인스턴스)으로, 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간이다.
typedef struct Animal {
    ...
} Animal;
play(Animal); 
// 본래 C에서는 이런 형태로 사용해야 한다. 
// 근데 언뜻 보면, 이 형태는 play가 Animal을 한다고 보는게 더 맞다.
// 그래서 C++에서는 객체와 클래스 개념을 도입하여 아래와 같이 사용한다.
class Animal{
    ...
}
Animal animal;
animal.play();
  • 클래스(Class)는 사용자 정의 데이터형(User-Defined Data Type)으로, 같은 종류의 집단에 속하는 속성과 행동을 정의한 것이다.
    • 데이터 멤버와 멤버함수 등을 가질 수 있다.
    • 쉽게 말해, 객체의 설계도 라고 볼 수 있다.
    • 클래스는 실제로 존재하지 않는다. 설계도 상에 있다고 해서, 건물이 실제로 존재하지는 않는 것 처럼 말이다.
    • private 부분에 정의된 것은 같은 클래스 안에서만 접근할 수 있으며, 객체 외부에서는 접근할 수 없다.
      • 같은 클래스 이면서, 다른 객체인 경우는 private에 접근이 가능하다.
    • public 부분에 정의된 것은 객체 외부에서도 자유롭게 접근할 수 있다.
    • protected 부분에 대한 접근 권한은 private 와 public 사이에 준하나, 자세한 사항은 다른 곳에서 정리한다.
    • 클래스를 선언할 때, 기본적으로 생성자(Constructor)가 호출되며, 사용을 마치고 정리될 때는 소멸자 (Destructor)가 호출된다. 이는 정의에 명시하지 않아도, 컴파일러가 자동으로 생성한다.

추상화(Abstraction)

  • 추상화(Abstraction) : 객체 지향 프로그래밍에서 중요한 개념으로, 객체들이 가진 공통의 속성과 행동을 묶어서 일반화하는 것을 의미한다. 이를 통해 객체들을 보다 쉽게 이해하고 관리할 수 있다.
  • 컴퓨터 상에서 현실 세계를 100% 표현하기에는 무리가 있기에, 컴퓨터에서 처리할 수 있도록 적절히 바꾸는 과정이라고 생각하면 된다.
  • 예를 들어, 자동차, 오토바이, 트럭 등 모든 종류의 차량은 운송 수단이라는 공통적인 수단을 가지며, 이를 추상화하여 Vehicle 이라는 개념을 만들어 낼 수 있다.
  • 이렇게 만들어진 추상화된 개념은 실제 객체가 아니다. 객체를 설계하는 데 유용하게 사용된다.
  • 또한 추상화는 코드의 재사용성을 높여준다. 구체적인 구현과 분리된 추상적인 개념을 만들어 낼 수 있고, 이것을 기반으로 다양한 구현을 새로 만들어 낼 수 있다.

캡슐화(Encapsulation)

  • 캡슐화(Encapsulation) : 클래스를 정의할 때 데이터와 함수를 하나로 묶어서 관리하는 것을 의미한다.
  • 데이터를 보호하기 위해, 데이터 멤버는 private으로 선언하고, 멤버 함수를 사용해 접근한다.
  • 이를 통해, 외부에서 클래스 내부의 데이터를 마음대로 변경하는 것을 막아 정보의 은닉성을 보장할 수 있다.
  • 또한 사용자로 하여금, 객체가 내부적으로 어떻게 작동하는지 몰라도 사용할 수 있게 해준다.
  • 우리가 키보드를 치는데 이렇게 입력되는 것도, 우리는 내부적으로 어떤 일이 일어나서 화면에 우리가 친 글자가 표시되는 지는 모르지만, 사용할 수 있으니 캡슐화에 해당한다고 볼 수 있다.

Reference

CPP 레퍼런스 (명시적 캐스팅)

[C++] dynamic_cast (타입캐스트 연산자)

Leave a comment