i를 double 타입으로 형변환하는 것은 임시값을 만드는 것이다.
int형인 i를 double& 타입으로 변경하는 것은
i객체가 가리키는 주소를 8바이트의 메모리 덩어리인 double 객체로 변환하는 것이다. but, 실제 값 반환은 하지 않는다.
참조타입 변환은 메모리값만 반환되는 것이다!
value타입 변환은 임시값은 반환하는 것이다!
그럼에도 불구하고, a-3과 b-3이 에러 발생하지 않는 이유는
b-1은 암묵적 변환이어서 컴파일러가 사전에 오류를 발생하는 것이고,
a-3과 b-3은 명시적으로 변환연산자를 사용했기 때문이다.
단 그에 따른 책임은 순전히 유저가...
: 2개의 클래스 메모리 구조가 같으므로, 위에서 기본데이터 형변환 한것처럼
형변환이 이루어져야 하는데, 불가능하다.
왜냐하면, 어떤 기준에 의해서 변환을 해야 할지 알 수 없기 때문이다.
reinterpret_cast는 타입 형변환을 허용하지 않는다.
현재 2개의 클래스가 동일한 메모리 구조를 가지고 있어서 그러는 것같은데?
클래스 메모리 구조를 변경해보자!
-> 클래스 메모리 구조를 공부할때 선언 순서에 따라서 메모리가 나열된다는 것을 확인했는데, 거기에 맞춰서 변환이 이루어진 것이다.
float형으로 바꾸면, 7이 float형으로 변경된 값이 들어온다...
- 서로 다른 클래스 간의 형변환에서는 메모리 구조가 동일해야만 형변환이 가능한 것이다.
- 레퍼런스형 변환은 메모리 구조를 반환하는 것이다.
: 변함없다. 왜냐하면 레퍼런스 타입 형변환은 원래 있던 객체의 메모리 영역 크기만 변경하여 반환하는 것이기 때문이다.
a,b,c는 상식적으로 당연하다.
자식에서는 이미 부모의 멤버값을 가지고 있기 때문에,
부모로도 변환이 가능하다.
즉 큰 범위에서 작은 범위로 낮아지는 것을 생각하면된다.
하지만 d가 안되는 이유는 reinter~는 형변환을 허용하지 않기 때문이다.
부모에서 자식으로의 형변환은 불가능하다.
작은 범위에서 큰범위로 변환하기에는 자식의 멤버들이 뭐가 있는지 정보를 알수 없어서이다.
적절한 생성자를 정의한다면 부모에서 자식으로의 형변환이 가능하다!
: 참조를 이용한 타입 형변환은 메모리를 확장하거나, 축소한다.
: 자식의 멤버값 유효하게 하기
value 타입 변환은 결과로 임시 객체가 생성되는 것이다.
reference 타입 변환은 객체의 메모리의 크기를 변경되는 것이다.
자식에서 부모로의 형변환은 상식적으로 가능하다.
부모에서 자식으로의 형변환은 값 타입에서는 금지되지만,
ref타입에서는 유저가 직접 형변환 할 경우에는 가능하지만, 책임은 유저가.
static_cast는 오로지 상속에서만 사용가능하다.
reinterpter_cast는 참조타입이나 포인터 타입으로의 변환만 가능하다.
: 포인터는 어쨋든 4바이트 혹은 8바이트의 메모리 블록이므로 문제 없을 것이라 생각하지만, 문제를 발생시킬 수 있다.
포인터 타입 변환을 하게 되면 기존 객체가 차지하는 메모리 영역을 적절히 조정하여 주소를 반환하는 것이다.
a는 암묵적인 변환인데 컴파일러가 관련없는 클래스여서 거부하는 것이다.
b는 명시적으로 변환하는 것인데 내부 값 달라도 책임 안짐
c는 static_cast는 상속에서만 가능하다.
d는 강제적인 형변환이다. //포인터여서 가능하다.
-> reinterpret_cast는 굉장히 무섭고 위험한 형변환 친구다...
-> 부모에서 자식으로의 암묵적인 형변환은 올바르지 못하므로 컴파일러가 막고 있다.
상속에서의 형변환은 대체적으로 이루어진다. 하지만 하향형변환은 올바른지는
전적으로 유저의 책임이다.
-> 다중 상속할경우, 부모 클래스의 메모리들이 선언한 순서대로 메모리에 배치되어 있다.
CParentB로 형변환을 하고 있다.
클래스의 메모리 배치를 보면, CParentB가 시작하는 메모리 값이고,
CParentA가 int형만 큼 차이가 나므로 4바이트 차이가 발생한 것이다.
: 가상함수가 존재할 경우 클래스 객체의 메모리 시작 위치에 가상함수 포인터가 생성된다.
-> pC에서 부모의 멤버인 mValue보다도 위에 가상함수 포인터의 메모리가 자리잡는 것이다.