class Father; /* 객체의 크기가 100 Byte */
class Son : public Father; /* 상속으로 인해 객체에 추가된 크기가 50 Byte */
Son *s = new Son; /* 객체의 시작주소가 0번지 부터 시작한다고 가정 */
Father *f = (Father *)s;
이라고 할 때,
Father 클래스는 100byte
Son 클래스는 50byte 사용한다고 할게요. 객체의 실제 주소는 0번지부터 시작하고.
그러면 컴파일러마다 구현방법이 다르지만 그 구현중 하나는
Father *f의 값은 0, Son *s는 50이 됩니다. (다시 말하지만 컴파일러 구현에 종속적이니까 다르게 구현할 수도 있습니다.)
이 경우 Father 클래스 관계된 메소드를 호출할때는 컴파일할 때 Son의 This주소를 Father의 포인터로 캐스팅해서 호출하게 되지요.
(별개의 두개의 클래스가 존재하고, 메서드를 호출할때 자동으로 해당 객체로 캐스팅해서 호출해준다.. 뭐 이런 개념이죠)
그래서 C++에서는 캐스팅이 위험하다는 겁니다. C++에서의 포인터는 단순하게 객체의 "위치"를 가리키는게 아니라
의견
답변은 아니고, 테스트하실 때 사용한 코드를 보여주실 수 있나요? 저도 궁금하네요.
저는 이렇게 생각했습니다.
.
다르면 안 될텐데요..
코드를 보여주실 수 있는지요? 저도 궁금하네요..ㅋㅋ
코드의 내용은 이렇습니다.
인터넷에 있는 소스를 그대로 테스트 해 본 것입니다.
여기서 CTCP_Connection 에 대해 생성자와 소멸자 함수를 추가해서 this 를 출력해 보았습니다.
메모리 주소가 다르게 나오던군요..ㅠㅠ
gilgil.net
multiple inheritance의 경우에는 this pointer가 달라질 수 있습니다만( http://www.gilgil.net/172 ) 올리신 코드에서 this를 출력하는 부분이 어디 있죠?
www.gilgil.net
상속의 경우 포인터의 주소가 달라 질 수 있습니다.
상속의 경우 포인터의 주소가 달라 질 수 있습니다.
이게 C++의 장점이자 단점/난점인데, 이게 컴파일러의 구현사항이라는 겁니다.
이라고 할 때,
Father 클래스는 100byte
Son 클래스는 50byte 사용한다고 할게요. 객체의 실제 주소는 0번지부터 시작하고.
그러면 컴파일러마다 구현방법이 다르지만 그 구현중 하나는
Father *f의 값은 0, Son *s는 50이 됩니다. (다시 말하지만 컴파일러 구현에 종속적이니까 다르게 구현할 수도 있습니다.)
이 경우 Father 클래스 관계된 메소드를 호출할때는 컴파일할 때 Son의 This주소를 Father의 포인터로 캐스팅해서 호출하게 되지요.
(별개의 두개의 클래스가 존재하고, 메서드를 호출할때 자동으로 해당 객체로 캐스팅해서 호출해준다.. 뭐 이런 개념이죠)
그래서 C++에서는 캐스팅이 위험하다는 겁니다. C++에서의 포인터는 단순하게 객체의 "위치"를 가리키는게 아니라
"핸들"처럼 사용된다고 생각하시는게 낫습니다. 다른말로 하면 C처럼 저수준에서의 지지고 볶고 하시면 위험합니다.
gilgil.net
multiple inheritance가 아닌 parent class가 하나일 경우에는 해당 객체에 대해서 부모 클래스 casting pointer와 자식 class casting pointer의 값은 다르지 않습니다.
www.gilgil.net
지금 Effective C++이 없어서 인용할 수
지금 Effective C++이 없어서 인용할 수 없어 아쉬운데,
제 기억에 그 책에서 언급하기로 말 그대로 컴파일러 종속적이기 때문에
이론적으로는 얼마든지 다르게 나올 수 있다는 거죠.
따라서 이식성을 고려하거나 다른 눈에 보이지 않는 버그를 생성하지 않으려면
원천적으로 저수준의 조작은 하지 말아야 한다는게 제 글의 요지였습니다.
Effective C++ 3판 항목 27, "사실
Effective C++ 3판 항목 27,
"사실 C++에서는 다중 상속이 사용되면 이런 현상이 항상 생기지만, 심지어 단일 상속인데도 이렇게 되는 경우가 있습니다."
(*여기서 현상은 업캐스팅 했을 때 포인터 값이 달라지는 현상을 지칭함)
"객체의 메모리 배치구조를 결정하는 방법과 객체의 주소를 계산하는 방법은 컴파일러마다 천차만별입니다. 그러니까, 어떤 플랫폼에서의 '메모리 배치를 다 꿰고 있어서' 캐스팅을 했을 때 문제가 없었을지라도 다른 플랫폼에서 그게 또 통하지는 않는다는 이야기죠."
"이를테면, 어떤 객체의 주소를 char* 포인터로 바꿔서 포인터 산술 연산을 적용하는 등의 코드는 거의 항상 미정의 동작을 낳을 수 있다는 이야기 입니다."
댓글 달기