블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
    - 복습
     → 전역변수와 이름이 겹칠 때 ::를 사용하면 전역을 뜻한다.
    ※ 잠시 JAVA의 main()을 생각해 보면 자바는 매인함수가 클래스 안에 있다.
    class ~~~~
    {
          public static void main()
    }
     → 즉, 객체안에 있는 함수이다.
     → 프로그램은 진입점(엔트리 포인트)을 항상 생각해야 한다.
     → C, C++등은 main()이며, WINAPI는 WinMain()이 엔트리 포인트
     → 자바는 main()이 클래스 안에 있으므로 객체가 생성되지 않으면 main을 호출할 수 없다. 따라서 static이 앞에 붙어 있다.(static은 정적이므로 컴파일 단계에서 main()을 생성하게 한다.)
     → JAVA Test
    class test
    {
      static int A; // test의 멤버
      public static void main(String[] args) // static으로 실행전에 main() 생성
      {
        A = 100// A가 static이 붙지 않았으므로 에러.
      
        System.out.println("Hello");      
        System.out.println("A");      
        emb.test(); // 현재 디렉토리 내에 emb 클래스가 있는지 찾는다.
        //kkk.test(); // kkk의 클래스가 없으므로 에러
      }
    }
    class emb
    {
      public static void test()
      {
        System.out.println("Test Method");
      }
    }

     → JAVA Test


    ※  윈도우에서 java 가상머신은 기본으로 깔려있고 컴파일러는 설치해야 한다.
     → 자바는 클래스 단위로 컴파일(C로 치면 object). 즉, 객체 단위로 컴파일 한다.
     → 따라서 위와 같이 컴파일 하면 class 파일이 test와 emp 두개가 생성되는 것을 확인할 수 있다.

     → C++로 돌아가서

    #if 1
    #include<iostream.h>
    #else
    #include<stdio.h>
    #endif

    class emb
    {
      //static int A;
      public :
        static void test()
        {
          //A  = 100;
          //cout << A << endl;
          cout << "test" << endl;
          return ;
        }    
    };
    int main()
    {
      //emb OBJ;
      //OBJ.test(); // 객체 기반 호출(객체가 있을 때만 가능)
      emb::test(); // static 기반 호출(static 함수이므로 가능)

      return 0;
    }


    → 위의 예제에서 헤더파일 include에 전처리 기법을 보면 
    #if 1
    #include<iostream.h>
    #else
    #include<stdio.h>
    #endif

     → if 문을 0으로 하면 else 문으로 실행되고 1로 하면 if의 헤더가 적용된다.
     → OBJ.test(); // 객체 기반 호출(객체가 있을 때만 가능)
      emb::test(); // static 기반 호출(static 함수이므로 가능)



    - 자동차 클래스 작성 예제
    #if 1
    #include<iostream.h>
    #else
    #include<stdio.h>
    #endif

    // 자동차 클래스
    class car
    {
      private:
        unsigned int uiNumber;
      public:
        // 생성자 - 자동 호출 된다.(반환형이 없는 특수한 경우)
        // 객체를 생성할 때 만들어 진다.
        // 생성자는 여러개를 만들 수 있으나 소멸자는 하나만 만들 수 있다.
        car() // 인자가 없는 생성자를 디폴트 생성자라 한다.
        {
          cout << "Car class 생성자 호출" << endl;
        }
        car(unsigned int uiNumber) // 자동차 일련번호
        {
          (*this).uiNumber = uiNumber;
          cout << this->uiNumber << "Car class 생성자 호출" << endl;
        }
        ~car() // 소멸자 - 앞에 틸드(~)를 붙인다. main함수가 종료되기 전에 호출된다.
        {
          cout << "CAR class 소멸자 호출" << endl;
        }
    };

    int main()
    {
      cout << "---------------------" <<endl;
      cout << "1" <<endl;
      
      car OBJ1;
      car OBJ2;
      car OBJ3;
      cout << "2" <<endl;  
      car OBJ4;
      car OBJ5;
      
      cout << "3" <<endl;
      cout << "---------------------" <<endl;
      return 0;
    }

     → 생성자와 소멸자를 살펴보면
     → 우선 생성자와 소멸자는 반환형이 없으며, 이는 특수하다.
     → 객체를 생성할 때 만들어 지며 생성자는 여러개를 만들 수 있으나 소멸자는 하나만 만들 수 있다.
     → 인자가 없는 생성자를 디폴트 생성자라 한다.
     → 소멸자는 앞에 틸드(~)를 붙인다. main 함수가 종료되기 전에 호출된다.

    #if 1
    #include<iostream.h>
    #include<stdlib.h>
    #else
    #include<stdio.h>
    #endif

    void test();
      
    // 자동차 클래스
    class car
    {  
      friend void test();
      private:
        unsigned int uiNumber; // 자동차 일련 번호
        unsigned char* ucpVendor; // 제조사
        
        // 생성자 - 자동 호출 된다.(반환형이 없는 특수한 경우)
        // 객체를 생성할 때 만들어 진다.
        // 생성자는 여러개를 만들 수 있으나 소멸자는 하나만 만들 수 있다.
        car() // 인자가 없는 생성자를 디폴트 생성자라 한다.
        {
          uiNumber = 0;
          ucpVendor = 0;
          cout << "Car class 생성자 호출" << endl;
        }
      
      public:
        car(unsigned int uiNumber) // 자동차 일련번호
        {
          ucpVendor = 0;
          (*this).uiNumber = uiNumber;
          cout << this->uiNumber << " Car class 생성자 호출" << endl;
        }
        car(unsigned int uiNumber, char *cpVendor) // 제조사
        {
          unsigned int uiLen; // 길이를 받기 위해
          
          uiLen = strlen(cpVendor);
          ucpVendor = (unsigned char*)malloc(uiLen+1); // NULL을 위해 +1
          strcpy((char *)ucpVendor,cpVendor);
          
          (*this).uiNumber = uiNumber;
          cout << this->uiNumber << cpVendor<< " Car class 생성자 호출" << endl;
        }
        ~car() // 소멸자 - 앞에 틸드(~)를 붙인다. main함수가 종료되기 전에 호출된다.
        {      
          if(0 !=  ucpVendor)  
          {
            free(ucpVendor);
          }
          cout << uiNumber << " CAR class 소멸자 호출" << endl;
        }
    };

    int main()
    {
      cout << "---------------------" <<endl;
      
      car OBJ1(1"KIA");
      car OBJ2=2;
      car OBJ3=3;
      car OBJ4=4;
      car OBJ5=5;
      
      cout << "---------------------" <<endl;
      // car OBJ6; // 디폴트 생성자를 private로 만들었기 때문에
            // 생성되지 않는다.(기법으로 사용 가능)
            // 소멸자에는 절대 pivate를 쓰지않는다.
          
      return 0;
    }

    void test()
    {
      car OBJ6;
    }

     → 결과

    → 살펴보면 객채가 1, 2, 3, 4, 5의 순서로 생성되고 5, 4, 3, 2, 1의 순서로 소멸됨이 보인다.

    → 생성자가 private면 객체를 생성하지 못한다.(기법으로 사용할 수 있다.→ 의도적으로 접근 생성자를 이용)

    → 전역변수의 사용(friend 사용법)
      friend void test()
    → 클래스 안에 friend로 함수를 선언하여(friend void test()) test()가 OBJ 생성이 가능하게 한다.
    → friend의 사용은 위험할 수 있다. 은닉을 해제하는 것이므로 main() 등에는 절대 쓰면 안된다.
    ※ encapsulation(데이터의 은닉 - private)
    ※ overloading(다양성)
     


    - 상속
     → 형식

    // JAVA
     class A
    {
    };
    C extends A
    {
    };
    // C++
    class A
    {
    };
    class C:A
    {
    };
     


    - 상속을 이용한 자동차 클래스 제작 예제

    #if 1
    #include<iostream.h>
    #include<stdlib.h>
    #else
    #include<stdio.h>
    #endif

    void test();
      
    // 자동차 클래스
    class car
    {  
      // 상속 받은 클래스만 사용할 수 있다.
      protected:
        unsigned int uiSpeed;
        
      // 클래스 내에서만 사용할 수 있다.
      private:
        unsigned int uiNumber; // 자동차 일련 번호
        unsigned char* ucpVendor; // 제조사
        
        // 생성자 - 자동 호출 된다.(반환형이 없는 특수한 경우)
        // 객체를 생성할 때 만들어 진다.
        // 생성자는 여러개를 만들 수 있으나 소멸자는 하나만 만들 수 있다.
        car() // 인자가 없는 생성자를 디폴트 생성자라 한다.
        {
          uiNumber = 0;
          ucpVendor = 0;
          cout << "Car class 생성자 호출" << endl;
        }  
      // 전체가 사용할 수 있다.
      public:
        car(unsigned int uiNumber) // 자동차 일련번호
        {
          ucpVendor = 0;
          (*this).uiNumber = uiNumber;
          cout << this->uiNumber << " Car class 생성자 호출" << endl;
        }
        car(unsigned int uiNumber, char *cpVendor) // 제조사
        {
          unsigned int uiLen; // 길이를 받기 위해
          
          uiLen = strlen(cpVendor);
          ucpVendor = (unsigned char*)malloc(uiLen+1); // NULL을 위해 +1
          strcpy((char *)ucpVendor,cpVendor);
          
          (*this).uiNumber = uiNumber;
          cout << this->uiNumber << cpVendor<< " Car class 생성자 호출" << endl;
        }
        ~car() // 소멸자 - 앞에 틸드(~)를 붙인다. main함수가 종료되기 전에 호출된다.
        {      
          if(0 !=  ucpVendor)  
          {
            free(ucpVendor);
          }
          cout << uiNumber << " CAR class 소멸자 호출" << endl;
        }    
    };
    class K5:car // car 클래스의 public을 상속 받는다..
    {
      public:
        K5() // 생성자
        :car(1234"KIA")
        {
          cout << "(생성자)K5가 생성되었습니다." << endl;
          uiSpeed = 0;
          //uiNumber = 7; // private이므로 에러
        }
        ~K5(void// 소멸자
        {
          cout << "(소멸자)K5가 생성되었습니다." << endl;
        }
        void speedUp(void)
        {
          uiSpeed = uiSpeed+10;
          if(100<uiSpeed)
          {
            uiSpeed = 100;
          }
          cout << "지금 속도는 " << uiSpeed << "Km입니다." << endl;
          return ;
        }
        void speedDown(void)
        {
          if(0==uiSpeed)
          {
            uiSpeed = 0;
          }
          else
          {
            uiSpeed = uiSpeed-10;
          }
          cout << "지금 속도는 " << uiSpeed << "Km입니다." << endl;
        }
          
    };

    int main()
    {
      unsigned char ucVal;
      K5 OBJ;  
      car OBJ2(5678"싸제 자동차");
      // OBJ2.uiSpeed = 100;// protected라 상속 클래스에서만 사용 가능
      while('q' != ucVal)
      {
        cout << "명령을 입력하시오" << endl;  
        cin >> ucVal;
        if('u' == ucVal)
        {
          OBJ.speedUp();
        }
        if('i' == ucVal)
        {
          OBJ.speedDown();
        }
      }
      
      return 0;
    }
     → main 함수가 운전자(소유주)
     → K5를 운전한다.
    ※ class 를 struct로 바꾸어도 같다. 단, struct는 default가 public이고, class는 default가 private이다.
     → 'u' 키를 누르면 속도가 10km씩 올라가고 'i'키를 누르면 속도가 10km씩 내려간다.
     → 실행 화면 (상속 기능만 구현해서 컴파일 했을 시)

     → 실행 화면

     

    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함