상속된 객체와 메모리 관계 소스로 총정리( 다형성 )



//Inher_A, Inher_B, Inher_C 클래스 정의
 


//상속과 메모리관계 총 정리(다형성)
//엄청 중요한 내용 

 //////////////////////////////////////////////////////////
//
// 연습 1
//
// 클래스와 메모리 관계에 대해서 알아보자!
//
//////////////////////////////////////////////////////////


int SizeA = sizeof(Inher_A); 
int SizeB = sizeof(Inher_B);
int SizeC = sizeof(Inher_C);

printf("Inher_A타입의 사이즈는? : %d 입니다\n", SizeA ); //4가 나와야함 (내꺼만)
printf("Inher_B타입의 사이즈는? : %d 입니다\n", SizeB ); //8이 나와야함 (부모꺼 내꺼)
printf("Inher_C타입의 사이즈는? : %d 입니다\n", SizeC ); //12가 나와야함 (조상꺼 부모꺼 내꺼)

//주의:private 변수도 메모리에 할당은 된다!! 접근만 안될뿐!!


//////////////////////////////////////////////////////////
//
// 연습 2
//
// 객체를 생성해서 자기함수를 불러보자!
//
//////////////////////////////////////////////////////////

//=========== 실험1 =============
//동적할당함
Inher_A* ptrA = new Inher_A;
Inher_B* ptrB = new Inher_B;
Inher_C* ptrC = new Inher_C;
//각자 자기의 멤버함수 호출
ptrA->SetDataA(3);
ptrB->SetDataB(4);
ptrC->SetDataC(5);

//=========== 실험2 =============
//부모 포인터로 자식을동적할당함
Inher_A* ptrD = new Inher_A;
Inher_A* ptrE = new Inher_B;
Inher_A* ptrF = new Inher_C;
//각자 자기의 멤버함수 호출
ptrD->SetDataA(6);
//ptrE->SetDataB(5); //*2* 에러남 (포인터 정적타입으로 정적바인딩되어서 Inher_A의 멤버함수만 접근가능)
//ptrF->SetDataC(4); //*3* 에러남 (포인터 정적타입으로 정적바인딩되어서 Inher_A의 멤버함수만 접근가능)


//====설명===
//실제로 *2*,*3*번은 자기만큼의 메모리할당을 한것이다. 
//하지만 멤버함수의 접근은 안되고 있는 것이다.(정적바인딩으로 인해)

//심심한 사람들은 여기서 브레이크포인트를 이용하여 디버깅 GoGo

//====문제====
//여기서 ptrE, ptrF 로 자기 자신 함수를 불러들이기 위해선 ?????????
//=> 자기자신으로 포인터를 캐스팅 연산하면 된다!! ( 당연한거 )

Inher_B* ptrG = static_cast <Inher_B*> (ptrE); 
Inher_C* ptrH = static_cast <Inher_C*> (ptrF);

ptrG-> SetDataB(6);
ptrH-> SetDataC(5);

//여기까진 상관이 없는데 ㅡ 
//delete 해줄때 에러가 난다!!!!( 왜냐?! 이유는 밑에 정리 )


//////////////////////////////////////////////////////////
//
// 연습 3
//
// 주제:상속과 메모리할당
// 동적할당과 참조하는 포인터!!!
//
//////////////////////////////////////////////////////////

//위에 사이즈계산한것을 생각해보면,
//Inher_A : 4바이트
//Inher_B : 12바이트 라는것을 알수 있다.

//사이즈를 염두해두고, 이 두개의 구문을 이해하면 다형성 끝이다!

//Inher_A* ptr = new Inher_C; //*1* Inher_C는 12바이트를 쓰는데 Inher_A포인터는 4바이트를 잡고있음 => 12바이트 할당하고 4바이트만 참조하는 격
//Inher_C* ptr2 = new Inher_A; //*2* Inher_A는 4바이트를 쓰는데 Inher_C포인터는 12바이트를 잡고있음 => 4바이트 할당해놓고 12바이트 참조하는 격

//====설명====
//동적할당이 되므로, 힙메모리에 할당이 된다.
//*1*은 부모포인터로 자식을 가르키니 성공(0)
//*2*는 자식포인터로 부모를 가르키니 에러(X)

//이것을 해제할때는 엄청난 에러 발생!
//12바이트짜리를 4바이트만 잡고있어서 해제할경우는 에러는 안남 (하지만 이것도 메모리가 남아있기때문에 문제)
//4바이트짜리를 12바이트 잡고있는경우 해제할때 에러남!


//====예제===== 
//위의 내용을 예제로 설명

unsigned char* c = (unsigned char*) new unsigned int;
*c = -1; //숫자를 꽉채움 c는 255
printf("C의 값은? : %d입니다. ", *c);

unsigned int* i = (unsigned int*) new unsigned char;
*i = -1; //숫자를 꽉채움 c는 255
printf("i의 값은? : %d입니다. ", *i);

//delete 해주면 바로 터짐!
//delete c; //크게 잡고 적게 없애는 격 
//delete i; //작게 잡고 크게 없애는 격

//둘다 말도 안되는 경우지만 에러는 i만 난다 (작게잡고 크게 메모리 없애는 경우니까?)
//둘다 메모리 안지우면 에러 안남


//////////////////////////////////////////////////////////////////////////
//즉 부모포인터로 자식객체를 받는 이유는?
//=> 부모포인터하나도 많은 자식을 할당할수 있다.
//=> 부모의 멤버함수 밖에 못씀
//=> virtual을 쓰면 동적할당 가능하기때문에 자식들것도 받을수 있다!!!


delete ptrA;
delete ptrB;
delete ptrC;


 



오늘 공부한 내용중 중요한 내용이 있어서 정리해봤다.
소스는 밑에 첨부하겠음!



이 글을 공유하기

댓글

Designed by JB FACTORY