본문 바로가기

C 언어/C++

c++ 기초단계 (11/22)

가상이 아닌 함수는 포인터의 정적인 형을 근거로 구동되지만, 가상 함수는 가리키고 있는 객체의 동적인 형을 근거하여 구동된다.

 

공통된 포인터로 다양한 객체를 가리킬 수 있다.

 

Musician은 추상적인 클래스

 11:     virtual void play() = 0;  //순수가상함수(첨보는것)

단지 이것만 쓰면 에러

abstract 어쩌고저쩌고… abstract 추상적인 이라는 뜻

추상이란 뭘까…

실제 존재하지 않는것을 유추하는 것이다.

 

순수가상함수는 상속을 받게 되면 상속클래스내에 함수를 반드시 만들어 줘야 한다.

가상함수는 상속을 받더라도 만들지 않아도 된다.

순수가상함수가 있으면 추상클래스라 한다.

 

  1: //순수가상함수, 오버라이딩
  2: #include <iostream.h>
  3: 
  4: class Musician    //제일 상위클래스(object)
  5: {
  6:   public :
  7:     virtual  void Greet() = 0;  //제일 상위클래스 안에 함수앞 virtual
  8: //    {
  9: //      cout << "안녕하세요. 저는 뮤지션입니다." << endl;
 10: //    }
 11:     virtual void play() = 0;  //순수가상함수(첨보는것)
 12: //    virtual void play()  //함수인터페이스만 있음
 13: //    {
 14: //    }
 15: };
 16: 
 17: class Singer : public Musician  //상속
 18: {
 19:   public :
 20:     void Greet()
 21:     {
 22:       cout << "안녕하세요. 저는 가수입니다." << endl;
 23:     }
 24:     void play()
 25:     {
 26:       cout << "노래하는 중입니다." << endl;
 27:     }
 28: 
 29: };
 30: 
 31: class Drum : public Musician
 32: {
 33:   public :
 34:     void Greet()
 35:     {
 36:       cout << "안녕하세요. 저는 드럼입니다." << endl;
 37:     }
 38:     void play()
 39:     {
 40:       cout << "드럼 치는 중입니다." << endl;
 41:     }
 42: 
 43: };
 44: 
 45: class Bell : public Musician
 46: {
 47:   public :
 48:     void Greet()
 49:     {
 50:       cout << "안녕하세요. 저는 벨입니다." << endl;
 51:     }
 52:     void play()
 53:     {
 54:       cout << "벨 치는 중입니다." << endl;
 55:     }
 56: };
 57: 
 58: class Guitar : public Musician
 59: {
 60:   public :
 61:     void Greet()
 62:     {
 63:       cout << "안녕하세요. 저는 기타입니다." << endl;
 64:     }
 65:     void play()
 66:     {
 67:       cout << "기타 치는 중입니다." << endl;
 68:     }
 69: };
 70: 
 71: int main()
 72: {
 73: //  Musician M;
 74:   Singer S;
 75:   Drum D;
 76:   Bell B;
 77:   Guitar G;
 78:   Musician *p[4] = {&S, &D, &B, &G};
 79:   //동적기반호출 (객체를기반으로), for문 이용 간단하게 호출
 80:   for(int iCnt=0; iCnt<4; ++iCnt)
 81:   {
 82:     (*p[iCnt]).Greet();  //우선순위 높은 () 필수, p[iCnt]->Greet();
 83:   }
 84:   for(int iCnt=0; iCnt<4; ++iCnt)
 85:   {
 86:     (*p[iCnt]).play();  //우선순위 높은 () 필수, p[iCnt]->Greet();
 87:   }
 88: 
 89:   //정적기반호출, 코드마다 호출해줘야하는 단점
 90: /*  M.Greet();  
 91:   S.Greet();
 92:   D.Greet();
 93:   B.Greet();
 94: */
 95:   return 0;
 96: }
 97:  
 98: 

 

순수가상함수

 

c++ 창시자는 누구 –> bjarne stroustrup

자바는 다중 상속이 없는 대신 인터페이스 클래스가 있다.

 

 

  1: //생성자, 복사생성자, 대입연산자, 소멸자는 왜 필요한가(추가로 프린트함수)
  2: //동적할당할 때 문제가 생기기 때문이다
  3: //virtual은 소멸자와 print에만 왜 쓰는지?
  4: //
  5: #include <iostream.h>
  6: 
  7: class Music
  8: {
  9: 	public :
 10: 		int *p;
 11: 		Music()
 12: 		{
 13: 			cout << "Music 디폴트 생성자 호출" << endl;
 14: 			p = new int;
 15: 			*p = 100;
 16: 		}
 17: 		virtual ~Music()	//소멸자 앞 가상 붙이면 다시 되돌아온다
 18: 		{
 19: 			cout << "Music 소멸자 호출" << endl;
 20: 			delete p;
 21: 		}
 22: 		virtual void print(ostream * o)	//반드시 virtual
 23: 		{
 24: 			*o << *p << endl;
 25: 		}
 26: };
 27: 
 28: class Rock : public Music
 29: {
 30: 	public :
 31: 		int *p2;
 32: 		Rock()
 33: 		{
 34: 			cout << "Rock 디폴트 생성자 호출" << endl;
 35: 			p2 = new int;
 36: 			*p2 = 200;
 37: 		}
 38: 		~Rock()
 39: 		{
 40: 			cout << "Rock 소멸자 호출" << endl;
 41: 			delete p2;	
 42: 		}
 43: 		void print(ostream * o)
 44: 		{	
 45: 			*o << "p가 가르키는 곳의 값 " << *p << endl;
 46: 			*o << "p2가 가르키는 곳의 값 " << *p2 << endl;
 47: 		}
 48: };
 49: 
 50: ostream & operator<<(ostream & o, Music & r)	//외부에선언 내부에서 쓰는게 아니니깐
 51: {
 52: 	r.print(&o);	//r.print(&cout);
 53: 	return o;
 54: }
 55: 
 56: ostream & operator<<(ostream & o, Rock & r)
 57: {
 58: 	r.print(&o);
 59: 	return o;
 60: }
 61: 
 62: int main()
 63: {
 64: //	Rock obj;	
 65: 	Music *p = new Rock;
 66: 	(*p).print(&cout);	//p -> print(&cout);
 67: 	delete p;		//Rock 소멸자 x
 68: 	return 0;
 69: }
 70: 

 

순수가상함수_00000

 

 

#include <iostream.h>
//클래스 함수포인터
class a
{
    public:
        void test()
        {
            cout << "hi" << endl;
        }
};

int main()
{
    a obj;
    obj.test();
    void(a::*fp)()=obj.test;
    (obj.*fp)();    //외우자
    return 0;
}

'C 언어 > C++' 카테고리의 다른 글

c++ 기초단계 (11/21)  (0) 2011.11.21
c++ 기초단계 (11/18)  (0) 2011.11.18
c++ 기초단계 (11/16)  (0) 2011.11.16
c++ 기초단계 (11/15)  (0) 2011.11.15
c++ 기초단계 (11/14)  (0) 2011.11.14