1. 변환 종류에 따른 변환
(1) 값 타입 변환
의미를 유지하기 위하여 원본 객체와 다른 비트열로 (원본과 거의 비슷하도록)재구성한다.
int main()
{
{
int a = 12345678; // 2의 보수로 저장됨
float b = (float)a; // 부동 소수점(지수와 유효숫자)
}
return 0;
}
// b에 a와 거의 유사한(같지 않은) 숫자가 저장됨
(2) 참조 타입 변환
비트열을 재구성하지 않고 데이터의 타입만 바꿈. 의미가 완전히 달라짐.
{
int a = 12345678; // 2의 보수로 저장됨
float b = (float&)a; // 부동 소수점(지수와 유효숫자)
}
포인터 타입 변환도 참조 타입 변환과 동일하게 사용할 수 있음.
2. 안전도에 따른 변환
(1) 안전한 변환
동일한 타입이면서 크기를 확대 변환하고자 할 때 안전한 변환이라고 한다. -> 의미가 동일함
ex) 업 캐스팅(Up Casting) : char -> short , short -> int, int -> __int64
(2) 불안전한 변환
서로 다른 타입을 캐스팅 할 때 불안전한 변환이라고 한다.
데이터가 손실될 수 있음! -> 의미가 달라질 수 있음
ex) 다운 캐스팅(Down Casting) : __int64 -> int, int -> short, short -> char
ex2) int -> float
3. 프로그래머의 의도에 따른 변환
(1) 암시적 변환
이미 알려진 타입 변환 규칙에 따라 컴파일러가 자동으로 타입 변환함.
{
int a = 12345678; // 2의 보수로 저장됨
float b = a; // 부동 소수점(지수와 유효숫자)
}
(2) 명시적 변환
프로그래머의 의도에 따라 타입을 강제로 변환함.
{
int a = 12345678; // 2의 보수로 저장됨
int* b = (int*)a; // 부동 소수점(지수와 유효숫자)
}
4. 연관 없는 클래스 사이의 변환
class Knight
{
public:
int hp = 10;
};
class Dog
{
public:
int _age = 1;
int _cuteness = 2;
};
int main()
{
{
Knight knight;
Dog dog = (Dog)knight; // 객체 knight를 Dog 타입으로 변환 불가
}
return 0;
}
단, 고의적으로 타입 변환 생성자 (또는 연산자)를 만들어주면 오류없이 빌드가 가능하다.
(1) 타입 변환 생성자
class Dog
{
public:
// 타입 변환 생성자
Dog(const Knight& knight)
{
_age = knight._hp;
}
// ~~~
(2) 타입 변환 연산자
// 타입 변환 연산자
operator Knight()
{
return (Knight)(*this);
}
5. 연관 없는 클래스 사이의 참조 타입 변환
int main()
{
{
Knight knight;
Dog& dog = knight;
}
return 0;
}
위에서는 오류가 발생한다(암시적 변환이 불가). 하지만 강제로 변환할 수 있다.
int main()
{
{
Knight knight;
Dog& dog = (Dog&)knight;
}
return 0;
}
위의 코드로 knight 주소를 따라가면 Dog형 타입의 데이터가 저장되어 있다고 주장할 수 있다(명시적 변환).
6. 상속 관계에 있는 클래스 사이의 타입 변환
class BullDog : public Dog
{
public:
bool _french;
};
(1) 값 타입 변환
{
BullDog bulldog;
Dog dog = bulldog;
}
Dog를 상속받은 자식인 bulldog는 dog 타입으로 변환이 가능하지만, 반대로 dog 타입의 객체는 bulldog이 될 수는 없다.
이 때 bulldog가 가지고 있던 멤버 변수 _french는 제거된다.
(2) 참조 타입 변환
{
// Dog dog;
// BullDog& bulldog = (BullDog&)dog;
BullDog bulldog;
Dog& dog = bulldog;
}
자식에서 부모 타입으로 변환은 가능하지만 반대의 타입으로 변환할 때는 명시적으로 변환해야 함.
6. 결론
(1) 값 타입 변환
실제 비트열도 바꾸며 논리적으로 말이 되도록( BullDog -> Dog O, Dog -> BullDog X) 변환함
(2) 참조 타입 변환
비트열을 바꾸지 않고 해당 데이터를 보는 관점을 바꾸는 것
안전하면 암시적으로 변환해 줌.
불안전하면 명시적으로 지정해야 변환해 줌.
'기초 C++ 스터디 > 객체지향' 카테고리의 다른 글
6-4. 얕은 복사, 깊은 복사 (0) | 2023.06.01 |
---|---|
6-3. 형(Type) 변환 : 포인터 (2) (0) | 2023.06.01 |
6-1. 동적 할당 (0) | 2023.05.31 |
5-7. 객체지향 정리 (0) | 2023.05.30 |
5-6. 연산자 오버로딩 (0) | 2023.05.30 |