간단한 클래스 상속 질문
조회수 743회
간단한 질문입니다.
class CObj
{
virtual int Add();
};
class CUnit :public CObjs
{
virtual int Add();
virtual void Check();
};
다음과 같은 간단한 상속구조가 있을시
CObj
포인터로 자식 클래스에 있는 check
에 정상적으로 접근이 가능한가요?
만약 접근이 정상적으로 가능하지가 않다면 부모쪽에서도 check
함수를 구현해야지만
부모 포인터로 자식쪽의 check
함수의 접근이 가능해지나요?
3 답변
-
public:
을 빼먹으신거 같은데 있다고 가정하겠습니다.CObj* p = new CUnit();
위와 같이
p
가 가리키는 주소는 실제론CUnit
의 인스턴스지만p
는CObj
의 포인터이기 때문에CObj
에 선언된 멤버만 접근할 수 있습니다.따라서 말씀하신 상황에서는 접근할 수 없습니다.
CUnit
의check()
를 호출하고 싶다면 말씀하신 것처럼CObj
에 해당 멤버 함수를 선언하는 방법을 사용하시거나p
를 다운 캐스팅 하셔야 합니다.다운 캐스팅을 할 때 static_cast나 dynamic_cast를 사용할 수 있습니다. static_cast는 해당 주소가 목적 타입임이 명확할 때 사용해야합니다. 예를 들어
p
가 가리키는 주소의 객체가CUnit
일 수 도있고CUnint2
일 수 도있으면 잘못된 캐스팅을 하게 됩니다.dynamic_cast는 상속 관계를 런타임에서 계산하기 때문에 아래처럼 캐스팅을 못 할 경우를 알려줘서 이에 대한 처리를 프로그래머가 할 수 있습니다.
CObj* p = new CUnit(); if (CUnit* p2 = dynamic_cast<CUnit>(p)) p2->check();
-
접근 불가능 할 걸요?
부모에서 virtual로 선언해야 룩업 테이블이 생성되어서 상속 받은쪽의 같은 이름의 함수가 매핑되는데
그런 선언이 없으면 부모 클래스의 포인터는 자식이 뭘 가지고 있는지 알 수 없으니 없다고 에러가 뜨겠죠.
이 경우에는 부모 포인터를 down casting 해야 접근이 가능할겁니다.
-
정상적인 접근은 불가능합니다.
강제적인 접근은 가능합니다. 윗분께서 말씀하신 것처럼 다운캐스팅을 통해 접근은 가능합니다만 예측 불가능한 동작이 발생할 것 같아요~
댓글 입력