열혈강의 8장


객체 리스트를 만들 때

포인터를 사용하는 이유

: 미리 생성되어져 버림.


포인터 배열로 선언할 경우 할당될 시에 객체가 생성됨.


단순 오버라이딩 했을 때  a b c 선언에 따라 함수가 어떻게 나오나

버추얼로 했을 때 버추얼된 함수를 나타내는방법



1. 객체 포인터의 권한


class Character(){


public:

void fct1();


}


class Gunner() : public Character{


public:

void fct2();


}


class Sniper() : public Gunner{


public:

void fct3();


}


Base 클래스의 객체 포인터는 자기 자신의 객체 뿐만 아니라

Derived 클래스의 주소값을 가질 수도 있다.


IS - A 관계에 의한 이해

-->  스나이퍼와 건너는 캐릭터이다. 라고 말할 수 있다. 때문에 

Base클래스인 Character의 포인터는 건너와 스나이퍼를 포함 할 수 있다.


--> 반대로 캐릭터는 스나이퍼이다.

캐릭터는 건너이다. 라고 말할 수 없다.

게임에서 존재하는 캐릭터가 모두 스나이퍼일리는 없다.


따라서 스나이퍼 클래스와 건너 클래스의 객체는 캐릭터 클래스의 객체이다. 라고 말할 수 있다.


1 . Character* c = new Character();

2. Character* c = new Gunner();

3. Character* c = new Sniper();

///// Base 클래스의 객체 포인터는 하위 클래스의 주소값을 모두 저장할 수 있기 때문에 문제없는 선언이 된다.


4. Gunner* c = new Gunner();

5. Gunner* c = new Sniper();


6. Sniper* c = new Sniper();



1. Character 객체 타입으로 선언된 포인터가 Character 객체를 가르키고 있다.

--> 따라서 Character 객체 내의 fct1(); 함수만 호출가능하다.


2. 이번에는 Gunner객체를 가르키고 있다.

--> Gunner객체의 fct2() 함수의 호출이 가능할 것 같지만, Character 객체의 멤버 함수 fct1()만 호출 된다.


왜?? Character 객체 포인터는 가르키는 대상이 무엇이건 Character 객체 내의 멤버와 Character가 상속한 멤버에만 접근이 가능하다.


3. 위와 똑같은 이유 때문에 Character 객체의 멤버 함수 fct1()만 호출된다.


4. 이번 같은 경우는 Gunner객체의 포인터가 Gunner의 객체를 가르키고 있다. 

Character에 의해 상속되어지고 있기 때문에 Character의 fct1()와 Gunner의 fct2() 에 모두 접근이 가능하다.


5. 이번 경우에도 Gunner 객체의 포인터로 선언이 되었기 때문에

Gunner이 가지고 있는 fct2()와 상위 클래스 fct1()의 호출이 가능하다.


6. Sniper객체 포인터가 자기 자신을 가르키고 있다.

이 경우 Sniper 클래스는 Character 과 Gunner에 모두 상속되어지고 있기 때문에

fct1(), fct2(), fct3() 모두 접근 가능하다.




2. 함수 오버라이딩


class Character(){


public:

void fct();


}


class Gunner() : public Character{


public:

void fct();


}


class Sniper() : public Gunner{


public:

void fct();


}


1 . Character* c = new Character();

2. Character* c = new Gunner();

3. Character* c = new Sniper();

4. Gunner* c = new Gunner();

5. Gunner* c = new Sniper();

6. Sniper* c = new Sniper();


c -> fct();


1. Character 객체 내의 fct()가 호출된다. (당연한 말)

2. Character 객체 내의 fct()가 호출된다.

3. 마찬가지

4. Gunner의 멤버함수 fct()가 호출된다.

왜?? --> 이름이 같기 때문에 오버라이딩에 의해 Character의 fct()가 은닉되어 Gunner 객체의 fct()가 호출된다.


5. Gunner의 멤버함수 fct()가 호출

6. Sniper의 멤버함수 fct() 호출

--> 마찬가지로 함수 오버라이딩에 의해 Character, Gunner 의 fct()가 은닉되어 Sniper의 fct()가 호출 된다.




3. virtual


class Character(){


public:

virtual void fct();


}


class Gunner() : public Character{


public:

virtual void fct();


}


class Sniper() : public Gunner{


public:

virtual void fct();


}


1 . Character* c = new Character();

2. Character* c = new Gunner();

3. Character* c = new Sniper();

4. Gunner* c = new Gunner();

5. Gunner* c = new Sniper();

6. Sniper* c = new Sniper();


c -> fct();



1. Character의 fct();

2. Gunner의 fct();

--> Character의 객체 포인터임에도 불구하고 Gunner의 멤버함수가 호출된다. 왜??

가상함수로 선언되었기 때문에 어떠한 객체를 가르키던 오버라이딩된 함수만 호출되어지게 된다.

말그대로 '가상'함수이기 때문에


3. Sniper의 fct();   --->  fct는 가상함수이기 때문에 오버라이딩된 Sniper의 fct()가 호출된다.

4. Gunner의 fct();

5. sniper의 fct();

6. sniper의 fct();



--> 함수오버라이딩의 은닉의 기능과 더불어 virtual을 사용할 경우 재정의의 기능까지 할 수있다.


'C++' 카테고리의 다른 글

[C++] 연산자 오버로딩 // 열혈강의  (0) 2016.12.07
[C++] virtual 소멸자, virtual table // 열혈강의  (0) 2016.12.05
[C++] 기초4 // 열혈강의  (0) 2016.12.01
[C++] 기초3 // 열혈강의  (0) 2016.11.30
[C++] 기초2 // 열혈강의  (0) 2016.11.30

+ Recent posts