본문 바로가기
코스웨어/11년 내장형하드웨어

[내장형]이영진_2011년 11월 11일_일일보고서

by 알 수 없는 사용자 2011. 11. 11.
728x90
반응형

C++

전역변수와 지역변수가 이름이 같을 때 :: (scope) 연산자를 사용하면 전역변수를 뜻한다.

잠시 java를 살펴 보겟다.

java의 main()를 살펴보면 main()이 클래스 안에 있다는 것을 알 수 있다.

class ~~~~
{
           public static void main()
}


1. main()은 클래스 안에 있는 함수이다.

2. 프로그램은 진입점을 생각해야한다.

3. C, C++등은 main()이 진입점이며, WINAPI는 WinMain()이 진입점이다.

4. java는 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");
  }
}


<javac로 컴파일 방법>



<출력>



 실행결과를 알아보려면 java 명령어 뒤에 클래스 이름을 적는다.

java는 클래스 단위로 컴파일 된다. 위와 같이 컴파일 할 경우 test.class와 emb.class 두 개가 생성된다.

윈도우에서 java 가상머신은 기본으로 깔려있고, java 컴파일러의 경우는 프로그램을 설치해야 한다.

다시 C++을 살펴보겠다.

<예제 1>

#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 함수이므로 가능)

  return 0;
}


→위 예제에서 전처리문을 보면 #if를 사용하여 1을 하면 if문이 실행되고 0을 하면

   else문이 실행되게 하는 기법을 사용하고 있다.

OBJ.test();

→객체 기반 호출을 사용 (객체가 있을 경우만 사용된다.)

emb::test();

 클래스 기반 호출을 사용 (객체가 없어도 사용된다. 클래스 멤버 함수 반환형 앞에 static을 붙여준다.)

<예제 2>

#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 << "==============<1>================" <<endl;
  
  car OBJ1;
  car OBJ2;
  car OBJ3;
  cout << "==============<2>================" <<endl;
  car OBJ4;
  car OBJ5;
  
  cout << "3" <<endl;
  cout << "==============<3>================" <<endl;
  return 0;
}


생성자 & 소멸자

→ 생성자와 소멸자는 반환형을 사용하지 않는 특수한 경우이다.

→ 생성자는 클래스 안에 여러개를 만들 수 있지만, 소멸자는 하나만 만들 수 있다. 

→ 소멸자 앞에는 틸드(~)를 붙인다.

→ 인자가 없는 생성자를 default 생성자라고 한다.

<예제 3>

#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 << " 생성자 호출" << 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<< " 생성자 호출" << endl;
    }
    ~car() // 소멸자 - 앞에 틸드(~)를 붙인다. main함수가 종료되기 전에 호출된다.
    {      
      if(0 !=  ucpVendor)  
      {
        free(ucpVendor);
      }
      cout << uiNumber << " Car class 소멸자 호출" << endl;
    }
};

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

void test()
{
  car OBJ6;
}


<출력>



→ 위의 예제를 살펴보면 객체가 1,2,3,4,5의 순서로 생성되고 5,4,3,2,1의 순서로 소멸되는 것을 알 수 있다. 

→ 생성자가 private 속성을 가지면 외부에서 접근 할 수 없다. (default 생성자를 사용하지 못하게 의도적인

   기법으로 사용할 수 있다.)

→ friend는 외부에서 private 속성에 접근 할 수 있도록 허용해 주는 키워드이다. 접근하고자 하는 클래스

   내부에 등록하고 싶은 함수원형에 friend를 붙여 선언하면 된다. 

   그러나 friend는 private에 접근할 수 있지만 이것은 객체지향에 어긋나는 것으로 객체지향의 은닉성을 

   해제시키는 키워드라고 할 수 있다. 따라서 남용을 하지 않고 계획적으로 사용되어야 할 것이다.


<예제 4>

#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<< " 생성자 호출" << endl;
    }
    ~car() 
    {      
      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 << "입니다." << endl;
      return ;
    }
    void speedDown(void)
    {
      if(0==uiSpeed)
      {
        uiSpeed = 0;
      }
      else
      {
        uiSpeed = uiSpeed-10;
      }
      cout << "지금 속도는 " << uiSpeed << "입니다." << endl;
    }
      
};

int main()
{
  unsigned char ucVal;
  K5 OBJ;  
  car OBJ2(5678"KIA");
  // OBJ2.uiSpeed = 100;// protected라 상속 클래스에서만 사용 가능
  while('q' != ucVal)
  {
    cout << "명령을 입력하시오" << endl;  
    cin >> ucVal;
    if('u' == ucVal)
    {
      OBJ.speedUp();
    }
    if('i' == ucVal)
    {
      OBJ.speedDown();
    }
  }
  
  return 0;
}



<출력>
 


→ 위 예제는 상속에 대한 예제이다. 상속은 A라는 클래스와 B라는 클래스가 있을 때 A클래스의 

    private영역을 제외한 모든 것을 물려받는 것을 의미한다. 상속 사용방법은 B:A 이렇게 사용한다.
 
→ 상속을 하면 기본적으로 A의 생성자를 호출하고 B의 생성자를 호출하게 되는데, 이때 A의 

    생성자와 오버로딩이라면 B의 생성자 뒤에 K5():car(1234, "KIA") 와 같은 방법으로 호출하면 된다. 
   
   (단, private 속성은 아니어야한다.)

→ protected는 상속받는 클래스 외 접근이 불가능하게 해주는 키워드이다. 

728x90