Notice
Recent Posts
Recent Comments
Link
오븐 노트
[C++] 타입 변환 #1~2 본문
#include <iostream>
using namespace std;
// malloc -> void*를 반환하고, 이를 우리가 (타입 변환)을 통해 사용하였음.
class Knight
{
public:
int _hp = 10;
};
class Dog
{
public:
Dog()
{
}
// 타입 변환 생성자
Dog(const Knight& knight)
{
_age = knight._hp;
}
// 타입 변환 연산자
// 특이하게도 리턴 타입이 없음. Knight에서 모든 의미를 함축하고 있기 때문
operator Knight()
{
return (Knight)(*this);
}
public:
int _age = 1;
int _cuteness = 2;
};
class BullDog : public Dog
{
public:
bool _french;
};
int main()
{
// 1. 타입 변환 유형 (비트열 재구성 여부)
// [1] 값 타입 변환
// 특징) 의미를 유지하기 위해서, 원본 객체와 다른 비트열 재구성
{
int a = 123456789; // int => 2의 보수를 이용하여 데이터를 저장하는 방식
float b = (float)a; // float => 부동소수점(지수 + 유효숫자) 기법을 이용하여 데이터를 저장하는 방식
cout << b << endl;
}
// [2] 참조 타입 변환
// 특징) 비트열을 재구성하지 않고, '관점'만 바꾸는 것
// 거의 쓸 일은 없지만, 포인터 타입 변환도 '참조 타입 변환' 동일한 룰을 따르니 겸사겸사 공부
{
int a = 123456789;
float b = (float&)a;
cout << b << endl;
}
// 2. 안전도에 따른 분류
// [1] 안전한 변환
// 특징) 의미가 항상 100% 완전히 일치하는 경우
// 같은 타입이면서 크기만 더 큰 바구니로 이동
// 작은 바구니 -> 큰 바구니로 이동 ok (업캐스팅)
// ex) char -> short, short -> int, int -> __int64
{
int a = 123456789;
__int64 b = a;
cout << b << endl;
}
// [2] 불안전한 변환
// 특징) 의미가 항상 100% 일치한다고 보장하지 못하는 경우
// 타입이 다르거나
// 같은 타입이지만 큰 바구니 -> 작은 바구니 이동 (다운캐스팅)
// 의미가 완전히 달라지기 때문에 매우 조심할 필요가 있음
// 손실을 만드는 것이기 때문에 애당초 이런 코드 자체가 이상한 코드라고 볼 수 있음.
{
int a = 123456789;
float b = a;
short c = a;
cout << b << endl;
cout << c << endl;
}
// 3. 프로그래머 의도에 따른 분류
// [1] 암시적 변환
// 특징) 이미 알려진 타입 변환 규칙에 따라서 컴파일러 '자동'으로 타입 변환
{
int a = 123456789;
float b = a; // 암시적
cout << b << endl;
}
// [2] 명시적 변환
{
int a = 123456789;
int* b = (int*)a; // 명시적
cout << b << endl;
}
// 4. 아무런 연관 관계가 없는 클래스 사이의 변환
// [1] 연관없는 클래스 사이의 '값 타입' 변환
// 특징) 일반적으로는 불가능 (예외 : 타입 변환 생성자, 타입 변환 연산자)
{
Knight knight;
Dog dog = (Dog)knight; // 타입 변환 생성자
Knight knight2 = dog; // 타입 변환 연산자
}
// [2] 연관없는 클래스 사이의 참조 타입 변환
// 특징) 명시적으로는 가능
{
Knight knight;
// 어셈블리의 관점 : 포인터 = 참조
// [ 주소 ] -> [ Dog ]
Dog& dog = (Dog&)knight;
dog._cuteness = 12; // 건들면 안되는 메모리를 건드릴 위험있음
}
// 5. 상속 관계에 있는 클래스 사이의 변환
// [1] 상속 관계 클래스의 값 타입 변환
// 특징) 자식 -> 부모 ok / 부모 -> 자식 no
{
//Dog dog;
//BullDog bulldog = (BullDog)dog; // 실패
BullDog bulldog; // 타입 변환 생성자를 만들면서 기본 타입 생성자가 막히기 때문에 error 발생
Dog dog = bulldog;
}
// [2] 상속 관계 클래스의 참조 타입 변환
// 특징) 자식 -> 부모 ok / 부모 -> 자식 (암시적 no) (명시적 ok)
{
//Dog dog;
//BullDog& bulldog = (BullDog&)dog;
// [ age cuteness french ]
BullDog bulldog;
Dog& dog = bulldog;
}
// 결론)
// [값 타입 변환] : 비트열 변환, 논리적으로 말이 되도록 바꾸는 변환
// - 논리적으로 말이 된다? (ex. BullDog -> Dog) ok
// - 논리적으로 말이 안 된다 ( ex. Dog -> BullDog, Dog -> Knight) no
// [참조 타입 변환] : 비트열은 그대로, 우리의 '관점'만 바꾸는 변환
// - 명시적 요구를 하면 가능은 하지만, 암시적으로는 안전성 여부와 연관 있음.
// -- 안전 (ex. BullDog -> Dog&) -> (암시적) ok
// -- 위험 (ex. Dog -> BullDog&) -> (암시적) no
// --- 메모리 침범 위험이 있는 경우는 암시적으로 해주지는 않음. (건드려서는 안되는 메모리 간섭 위험)
// --- 위험 감수까지 하며 명시적으로 선언시에는 가능.
return 0;
}
[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문 - 인프런 | 강의
C++ 카테고리의 글은 인프런 Rookiss님의 강의를 공부하며 정리하는 내용입니다.
이미 알고 있는 내용도 다시 정리 되어있을 수 있습니다.
모든 글은 제가 공부하기 위해 작성합니다.
'Develop > C++' 카테고리의 다른 글
[C++] 타입 변환 #4~5 (0) | 2023.02.15 |
---|---|
[C++] 타입 변환 #3 (0) | 2023.02.15 |
[C++] 동적할당 #3 (0) | 2023.02.08 |
[C++] 동적할당 #2 (0) | 2023.02.01 |
[C++] 동적 할당 #1 (0) | 2022.10.06 |