[C++] 타입 변환 2: 참조 타입 변환
타입 변환 2
인프런 Rookiss님의 'Part1: C++ 프로그래밍 입문' 강의를 기반으로 정리한 필기입니다.
😎[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문 강의 들으러 가기!
공통 부분 - Knight, Dog, BullDog
class Knight
{
public:
int _hp = 10;
};
class Dog
{
public:
Dog() { }
// 타입 변환 생성자
Dog(const Knight& knight)
{
_age = knight._hp;
}
// 타입 변환 연산자
operator Knight()
{
return (Knight)(*this);
}
public:
int _age = 1;
int _cuteness = 2;
};
class BullDog : public Dog
{
public:
bool _french; // 프렌치 불독
};
아무런 연관 관계가 없는 클래스 사이의 변환
1. 연관없는 클래스 사이의 '값 타입' 변환
- 연관없는 클래스 사이의 '값 타입' 변환은 일반적으로 안 됨
- 예외: 타입 변환 생성자, 타입 변환 연산자
Knight knight;
Dog dog = (Dog)knight;
Knight knight2 = dog;
2. 연관없는 클래스 사이의 참조 타입 변환
Knight knight;
// 어셈블리 관점에서는 '포인터 = 참조'
// [ 주소 ] -> [ Dog ]
Dog& dog = knight; // 다음과 같이 암시적으로 선언하면 통과X
Dog& dog = (Dog&)knight;// (Dog&)와 같이 명시적으로 선언하면 통과O
dog._cuteness = 12; // 건드리면 안되는 메모리를 건드리는 문제발생!
상속 관계에 있는 클래스 사이의 변환
[1] 상속 관계 클래스의 값 타입 변환
// Dog dog;
// BullDog bulldog = (BullDog)dog;
BullDog bulldog;
Dog dog = bulldog;
위의 경우 통과X, 아래의 경우 통과O
특징) 부모->자식 NO / 자식->부모 OK
[2] 상속 관계 클래스의 참조 타입 변환
Dog dog;
BullDog& bulldog = dog; // 통과X
BullDog& bulldog = (BullDog&)dog; // 통과O
// [age, cuteness, french ]
BullDog bulldog;
Dog& dog = bulldog;
결론
[값 타입 변환]
진짜 비트열도 바꾸고~ 논리적으로 말이 되게 바꾸는 변환
- 논리적으로 말이 된다? (ex. BullDog -> Dog) OK
- 논리적으로 말이 안 된다 (ex. Dog -> BullDog, Dog -> Knight) 안 됨
[참조 타입 변환]
비트열은 냅두고 우리의 '관점'만 바꾸는 변환
- 땡깡 부리면(명시적 요구) 해주긴 하는데, 말 안 해도 '그냥' (암시적)으로 해주는지는 안전성 여부를 연관 있음
- 안전하다? (ex. BullDog -> Dog&)
- '그냥' (암시적으로) OK
- 위험하다? (ex. Dog -> BullDog&)
- 메모리 침범 위험이 있는 경우는 '그냥' (암시적으로) 해주진 않음 (위험하니까)
- 명시적으로 정말 정말 하겠다고 최종 서명을 하면 OK
전체코드
더보기
#include <iostream>
using namespace std;
class Knight
{
public:
int _hp = 10;
};
class Dog
{
public:
Dog() { }
// 타입 변환 생성자
Dog(const Knight& knight)
{
_age = knight._hp;
}
// 타입 변환 연산자
operator Knight()
{
return (Knight)(*this);
}
public:
int _age = 1;
int _cuteness = 2;
};
class BullDog : public Dog
{
public:
bool _french; // 프렌치 불독
};
int main()
{
// -------- 아무런 연관 관계가 없는 클래스 사이의 변환 ----------
// [1] 연관없는 클래스 사이의 '값 타입' 변환
// 특징) 일반적으로 안 됨 (예외: 타입 변환 생성자, 타입 변환 연산자)
{
Knight knight;
Dog dog = (Dog)knight;
Knight knight2 = dog;
}
// [2] 연관없는 클래스 사이의 참조 타입 변환
// 특징) 명시적으로는 OK
{
Knight knight;
// 어셈블리 : 포인터 = 참조
// [ 주소 ] -> [ Dog ]
Dog& dog = (Dog&)knight;
dog._cuteness = 12;
}
// -------- 상속 관계에 있는 클래스 사이의 변환 ----------
// 특징) 자식->부모 OK / 부모->자식 NO
// [1] 상속 관계 클래스의 값 타입 변환
{
// Dog dog;
// BullDog bulldog = (BullDog)dog;
BullDog bulldog;
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) 안 됨
// [참조 타입 변환] : 비트열은 냅두고 우리의 '관점'만 바꾸는 변환
// - 땡깡 부리면(명시적 요규) 해주긴 하는데, 말 안 해도 '그냥' (암시적)으로 해주는지는 안전성 여부를 연관 있음
// -- 안전하다? (ex. BullDog -> Dog&) '그냥' (암시적으로) OK
// -- 위험하다? (ex. Dog -> BullDog&)
// --- 메모리 침범 위험이 있는 경우는 '그냥' (암시적으로) 해주진 않음 (위험하니까)
// --- 명시적으로 정말 정말 하겠다고 최종 서명을 하면 OK
return 0;
}
'⭐ Programming > C++' 카테고리의 다른 글
[C++] 타입 변환 4: 포인터 (0) | 2022.04.09 |
---|---|
[C++] 타입 변환 3: 포인터 타입 변환 (0) | 2022.04.08 |
[C++] 타입 변환 1: 값, 타입 변환 / 암시적, 명시적 변환 (0) | 2022.04.08 |
[C++] 동적 할당: new, delete (0) | 2022.04.07 |
[C++] 동적 할당: malloc, free, void*, double free, Use-After-Free (0) | 2022.04.07 |
댓글
이 글 공유하기
다른 글
-
[C++] 타입 변환 4: 포인터
[C++] 타입 변환 4: 포인터
2022.04.09 -
[C++] 타입 변환 3: 포인터 타입 변환
[C++] 타입 변환 3: 포인터 타입 변환
2022.04.08 -
[C++] 타입 변환 1: 값, 타입 변환 / 암시적, 명시적 변환
[C++] 타입 변환 1: 값, 타입 변환 / 암시적, 명시적 변환
2022.04.08 -
[C++] 동적 할당: new, delete
[C++] 동적 할당: new, delete
2022.04.07