코드를 한 줄씩 자세히 분석하여 설명드리겠습니다. 이 예제는 C++의 다양한 형변환 규칙과 형변환에 따른 동작 방식을 다루고 있습니다.
void func(float f) { }
void func(Parent* parent) { }
void func(const Child& child) { }
func 함수는 서로 다른 파라미터 타입을 받는 오버로드된 세 가지 버전을 정의합니다.func(float f): float 타입의 인자를 받습니다.func(Parent* parent): Parent 포인터를 받습니다.func(const Child& child): Child 클래스의 상수 참조를 받습니다.func 함수들은 전달된 인자의 타입에 따라 호출됩니다.class Test
{
public:
explicit operator bool() const
{
return true;
}
};
Test 클래스에 bool 타입으로의 변환 연산자를 정의했습니다.explicit 키워드를 사용하여 명시적 변환만 허용합니다. 즉, Test 객체를 bool로 변환할 때 자동 변환되지 않으며, 명시적으로 호출해야 합니다.class Parent { };
class Child : public Parent { };
Parent 클래스와 이를 상속받는 Child 클래스를 정의했습니다.Child는 Parent 클래스를 공개(public) 상속하며, 이를 통해 자식 클래스에서 부모 클래스 타입으로의 암시적 형변환이 가능합니다.main 함수int main()
{
float f = 1;
func(1);
float f = 1;에서 int 값 1이 float로 암시적 형변환됩니다.func(1);은 1을 float로 암시적 변환하여 func(float f) 버전을 호출합니다. char ch0 = 'a';
int num0 = ch0;
char ch0 = 'a';는 문자 'a'를 저장합니다.int num0 = ch0;는 char를 int로 암시적 형변환하며, 이는 promotion 또는 확대 변환이라고 불립니다. int num1 = 1000;
char ch1 = num1;
char ch1 = num1;은 int를 char로 암시적 변환하는 demotion(축소 변환)입니다. char의 크기보다 큰 값을 저장하려는 경우 데이터 손실이 발생할 수 있습니다. const int num2 = 10;
char ch2{ num2 };
char ch2{ num2 };에서 {}를 사용한 통합 초기화는 축소 변환이 필요한 경우 컴파일 타임에 오류를 발생시킵니다.num2가 char에 맞는 값이므로 정상적으로 초기화됩니다. unsigned short s0 = 40000;
cout << s0 + s0 << endl;
cout << typeid(s0 + s0).name() << endl;
s0 + s0에서 unsigned short 값이 int로 promotion되어 계산됩니다. typeid를 통해 결과 타입을 확인할 수 있습니다. unsigned int i0 = 4100000000;
cout << i0 + i0 << endl;
cout << typeid(i0 + i0).name() << endl;
i0 + i0에서 오버플로우가 발생합니다. unsigned int 타입으로 남으며, 결과 값이 unsigned int 범위를 초과해 오버플로우됩니다. unsigned int i1 = 10;
int i2 = -110;
cout << i0 + i2 << endl;
cout << typeid(i0 + i1).name() << endl;
i0 + i2에서 unsigned가 포함된 연산은 결과가 항상 unsigned가 됩니다. 따라서 int 값이 unsigned int로 암시적 변환되어 언더플로우가 발생할 수 있습니다. long long l0 = 10;
cout << l0 + i1 << endl;
cout << typeid(l0 + i1).name() << endl;
l0 + i1에서 i1은 long long 타입으로 암시적 변환되어 결과가 long long이 됩니다. float f = 1.f;
unsigned long long ull = 10ULL;
cout << typeid(f + ull).name() << endl;
f + ull에서 unsigned long long은 float 타입으로 변환되어 실수 연산이 수행됩니다.long double > double > float).Test 객체의 암시적 변환 Test t;
bool b = t;
if (t) {}
while (t) {}
t ? 1 : 2;
!t;
t && true;
false || t;
Test 객체 t를 bool로 암시적 변환하려 할 때 explicit 키워드로 인해 bool b = t;는 컴파일되지 않습니다.if, while, 삼항 연산자, 논리 연산자 등에서는 암시적 변환이 허용됩니다.const 형변환 int a = 1;
const int& b = a;
const int* c = &a;
int a는 const int& 또는 const int*로 암시적 형변환됩니다. 이는 상수화(const-casting)라고 하며, 원본 값 a의 수정은 허용되지 않습니다. Child c;
Parent* p0 = &c;
Parent& p1 = c;
func(&c);
func(c);
Child 타입의 객체 c를 Parent* 또는 Parent& 타입으로 암시적 변환할 수 있습니다. 이를 통해 부모 타입으로 형변환이 이루어집니다. (Child*)c;
(Child*)(c);
}
Child 객체로의 명시적 형변환을 보여줍니다.