이 코드를 한 줄씩 분석하여 설명드리겠습니다.
#include <iostream>
using std::cout;
using std::endl;
#include <iostream>
: 콘솔 출력에 필요한 cout
과 endl
을 포함하는 라이브러리입니다.using std::cout;
과 using std::endl;
: std
네임스페이스 없이 cout
과 endl
을 사용할 수 있도록 설정합니다.class Parent
{
public:
Parent() {}
explicit Parent(int i) {}
};
class Parent
: Parent
라는 이름의 클래스를 정의합니다.Parent() {}
: 기본 생성자로, 매개변수 없이 객체를 초기화할 때 사용됩니다.explicit Parent(int i) {}
: 정수형 인수를 받는 생성자입니다. explicit
키워드는 암시적 변환을 방지하여, Parent p = 10;
같은 코드가 오류를 발생하게 합니다.enum class Type
{
A, B, C
};
enum class Type
: Type
이라는 열거형 클래스입니다. A
, B
, C
라는 세 가지 열거형 값을 가집니다.enum class
를 사용하여 Type::A
와 같이 네임스페이스로 구분된 상수를 정의합니다. C++에서 일반 enum
보다 타입 안정성을 제공합니다.using ParentPointer = Parent*;
using ParentPointer = Parent*;
: Parent*
타입을 ParentPointer
라는 별칭으로 정의하여 가독성을 높입니다.void constCastFunc(int i)
{
const int& j = i;
int& k0 = (int&)j; // const_cast
// C스타일 캐스트보다 의도가 명확하다
int& k1 = const_cast<int&>(i);
}
void constCastFunc(int i)
: const_cast
를 사용하는 예제 함수입니다.const int& j = i;
: i
를 const int
참조로 바인딩하여 상수 참조로 만듭니다.int& k0 = (int&)j;
: C 스타일 캐스팅을 사용하여 j
의 상수성을 제거합니다. 이 방법은 명확하지 않으므로 지양하는 것이 좋습니다.int& k1 = const_cast<int&>(i);
: const_cast
를 사용하여 상수성을 제거합니다. C 스타일 캐스트보다 의도가 명확하여 코드의 가독성을 높입니다.int main()
{
// C 스타일 캐스팅
int num0 = (int)Type::A;
// 함수형 스타일 캐스팅
int num1 = int(Type::A);
int num0 = (int)Type::A;
: Type::A
열거형 값을 C 스타일 캐스팅으로 int
타입으로 변환합니다.int num1 = int(Type::A);
: Type::A
열거형 값을 함수형 스타일 캐스팅으로 int
타입으로 변환합니다. // C, 함수형 스타틸 캐스팅은 아래 세 개의 캐스팅을 시행한다
int i = 10;
float& f = (float&)i; // reinterpret_cast
const int& j = i;
int& k = (int&)j; // const_cast
i = (int)Type::A; // static_cast
// C, 함수형 스타일 캐스트보다는 C++의 cast를 사용하자
int i = 10;
: i
에 정수 10을 할당합니다.float& f = (float&)i;
: C 스타일 캐스팅으로 i
의 주소를 float&
타입으로 변환합니다. 이는 reinterpret_cast
와 같은 효과를 내며, 데이터의 의미를 변경하는 위험이 있습니다.const int& j = i;
: i
를 상수 참조로 바인딩합니다.int& k = (int&)j;
: C 스타일 캐스팅으로 j
의 상수성을 제거하여 int&
타입으로 변환합니다. 이는 const_cast
와 같은 효과를 냅니다.i = (int)Type::A;
: Type::A
열거형 값을 int
타입으로 변환하여 할당합니다. 이 변환은 static_cast
와 동일합니다. Parent p;
// 아래는 생성자 호출인가 변환인가?, 둘 다 맞음
p = Parent(10);
p = (Parent)10;
Parent p;
: Parent
클래스의 객체를 기본 생성자로 생성합니다.p = Parent(10);
: int
인자를 받는 Parent
의 생성자를 호출하여 p
에 할당합니다.p = (Parent)10;
: C 스타일 캐스팅을 사용하여 int
를 Parent
타입으로 변환합니다. 이는 생성자를 호출하는 것과 같은 효과를 냅니다. // 항상 생성자 호출은 아님
// 형변환임
ParentPointer *p = ParentPointer(&p);
// 형변환 사용
ParentPointer *p = static_cast<ParentPointer>(&p);
ParentPointer *p = ParentPointer(&p);
: C 스타일로 Parent
포인터를 ParentPointer*
타입으로 변환합니다.ParentPointer *p = static_cast<ParentPointer>(&p);
: static_cast
를 사용하여 Parent
포인터를 ParentPointer*
로 변환합니다. 이 방식이 더 명확하고 안전합니다. // static_cast가 생성자 호출로 쓰일수도 있음
p = static_cast<Parent>(10); // 생성자 호출
}
p = static_cast<Parent>(10);
: static_cast
를 사용하여 int
값을 Parent
로 변환하여 생성자를 호출합니다. 이 경우 Parent
생성자를 호출하게 됩니다.static_cast
, reinterpret_cast
, const_cast
는 C 스타일보다 의도를 명확하게 나타내고 안전하게 사용할 수 있습니다.reinterpret_cast
와 const_cast
사용 시 주의가 필요하다는 것을 강조하고 있으며, 명확한 의도를 가지고 C++ 스타일 캐스팅을 사용하는 것이 좋다고 제안하고 있습니다.