static_cast에서 허용이라는 것은 is a의 관계에 있는 포인터에 대해서만 점검하는 것인가요?
char c='A';
char* pc=&c;
int* pi=pc;
에서 컴파일러에 의해 허용되지 않는 문자. 여기서 컴파일이 이루어지지 않는 이유는 1byte 메모리에 4byte로 포인터 pi가 접근하려 하기 때문이다.
이 이유에 대해서는 별 이의를 제기할 수 있는 이유가 없지만
int i=70;
int* pi=&i;
char* pc=pi;
이것은 컴파일러에서 허용되지 않는다. 그래서 오류가 발생하는데.
그러나 pc에 의해 접근되는 메모리는 할당된 메모리 i가 의미하는 메모리를 초과하지 않는데도 왜 허용되지 않는지?
분명 pc로 접근하는 메모리는 i라는 4byte를 초과하지 않는데 왜 허용되지 않을까?
아래의 경우에서는
class CBase { public: int a; };
class CDerived : public CBase { public: int b; };
CDerived* pDerived = new CDerived;
CBase* pBase;
pBase = pDerived;
이 경우는 허용이 된다. 그 근거가 하위 클래스인 DDerived가 기반클래스인 CBase의 데이터를 포함하기 있기 때문이라는데.
즉 pBase는 pDerived의 허용 범위를 넘지 않기 때문이라는 것. 이런 의미에서 볼 때 두 번째 언급한 코드
int i=70;
int* pi=&i;
char* pc=pi;
의
char* pc=pi;
도 허용되어야 하지 않을까요? 안 되는 이유라 한다면
char와 int는 is a 가 아니기 때문이라고 할 수 있나요?
네.
네.
---
http://coolengineer.com
이것은 컴파일러에서 허용되지 않는다. 그래서 오류가
type 특성의 일부분일 뿐인 size를 기준으로 생각하지 마시고,
그보다 더 크고 일반적인 개념인 type의 다름을 기준으로 생각하시길 권합니다.
프로그래밍 언어는 추상적인 개념의 집합체이니, 추상적이고 일반적인 개념으로 이해해야 합니다.
어떤 객체를 마치 다른 타입의 객체인 것처럼 다룬다는 것은 여러가지 위험성을 내포합니다.
이웃 영역의 메모리 침범 문제, 정렬 제한, 잘못된 데이터의 읽기 및 쓰기...
따라서 C에서도 그런 방식은 일부에서만 허용되는 방식이었고,
객체지향 개념이 포함된 C++에서는 이에 대한 제한이 더욱 강화되었습니다.
C에서는 허용되던 범용 포인터로서의 void *와 char *의 역할이 제한된 것이 한 예입니다.
타입의 conversion에 대해서는, 일반적으로는 모두 허용되지 않는다고 생각하고
그중에 되는 사례 중심으로 보는 것이 좋습니다.
허용 범위를 넘지 않기 때문이라기보다는,
pDerived인 객체가 pBase인 것처럼 다루어 질 수 있는 특수한 형태(=상속관계)이기 때문에
저런 방식의 포인터 형변환이 가능한 것입니다.
구체적으로는 pDerived가 메모리 크기가 더 크고, 메모리 주소값 정렬 제한이 호환되며,
서로 겹치는 부분에 대해 내부 표현이 같고,
따라서 pBase의 대부분의 메소드가 pDerived에 그대로 적용 가능하기 때문입니다.
int는 char처럼 다뤄질 수 없습니다. 메모리 크기, 정렬 제한, 내부 표현 등과 같은 요소들에서 서로 호환되기 힘든 차이가 있습니다.
C에서는 모든 객체를 char로 쪼개어 접근할 수 있습니다만, C++에서는 더이상 아닙니다.
tunecolor님 질문들을 보고 있자면 꼭 공중에서부터 지어내려가는 건축물을 보는 것 같습니다.
그 단계까지 가는데 필요한 지식들이 빠진 상태로 윗부분 내용을 묻고 있습니다.
다른 글에서도 많이 들어본 충고겠지만,
제대로 된 기본서로 처음부터 다시 보십시오.
그것이 시간을 절약하는 길입니다.
댓글 달기