본문 바로가기
코스웨어/14년 스마트컨트롤러

2014년 10월 15일 수업일지 김용우

by 알 수 없는 사용자 2014. 10. 15.
728x90
반응형

C++

.static 멤버함수

static 멤버함수의 특성

l   선언된 클래스의 모든 객체가 공유

l   public으로 선언이 되면, 클래스의 이름을 이용해서 호출이 가능

l   객체의 멤버로 존재하는 것이 아님

≫ 주목해야 할 점은 객체의 멤버로 존재하는 것이 아니라는 부분!!(다음 코드는 Error)

#include <iostream>

using namespace std;

class smart
{
private:
  int inum1;
  static int num2;
public:
  smart(int n): num1(n)
  {}
  static void Adder(int n)
  {
    num1+=n;    //
컴파일 에러발생!!
    num2+=n;
  }
};
int smart::num2=0

Static 멤버함수인 Adder에서 멤버변수인 num1에 접근하는 것이 잘못된 이유.

l   객체의 멤버가 아니므로, 멤버변수에 접근X

l   객체생성 이전에도 호출이 가능

l   멤버변수에 접근을 한다고 해도, 어떤 객체의 멤버변수에 접근하는지 모름

static 멤버함수 내에서는 static 멤버함수와 static 멤버함수만 호출이 가능

static 멤버변수와 static 멤버함수를 잘 활용하면, 대부분의 경우에 있어서 전역함수와 전역변수를 대체할 수 있다!!!!

 

Ⅱ. const static

const static 멤버변수는, 클래스가 정의될 때 지정된 값이 유지되는 상수

#include <iostream>
using namespace std;

class CountryArea
{
public:
  const static int RUSSIA  =1707540;
  const static int CANADA  =998467;
  const static int CHINA  =957290;
  const static int SOUTH_KOREA  =9922;
};

int main(void)
{
  cout<<"
러시아 면적: "<<CountryArea::RUSSIA<<"km²"<<endl;
  cout<<"
캐나다 면적: "<<CountryArea::CANADA<<"km²"<<endl;
  cout<<"
중국 면적: "<<CountryArea::CHINA<<"km²"<<endl;
  cout<<"
한국 면적: "<<CountryArea::SOUTH_KOREA<<"km²"<<endl;
  return 0;
}


예제를 보다시피 선언과 동시에 초기화가 되었다. (월래는 클래스안에서 직접 초기화가 불가능하다.)

 

. 키워드 mutable

mutable이란? const함수 내에서의 값의 변경을 예외적으로 허용 하는 것.

 

 

#include <iostream>
using namespace std;

class smart
{
private:
  int num1;
  mutable int num2;
public:
  smart(int n1, int n2)
    :num1(n1), num2(n2)
  {}
  void ShowSmartData() const
  {
    cout<<num1<<", "<<num2<<endl;
  }
  void CopyToNum2() const
  {
    num2 = num1;
  }
};

int main(void)
{
  smart sm(1,2);
  sm.ShowSmartData();
  sm.CopyToNum2();
  sm.ShowSmartData();
  return 0;
}


num2 = num1; mutable 선언되었기에 변견이 가능하다.

 

Mutable 많이 사용하면 좋지 못한 키워드이다.

 

. 상속의 이해!!

여러 가지의 종류의 자동차들이 있다. 이러한 자동차들은 모양 생김새 크기 모두 다를 것이지만 공통적으로 자동차라고 지칭할 수 있는 특징이 있다. 예를 들면 바퀴, 엔진, 핸들, 엑셀, 브레이크, 기어, 문 등특성을 가지고 있다.

그런데 우리가 승용차 내에서 Ray와 에쿠스 등의 클래스를 만들고자 한다. 그런데 이러한 클래스를 만들 때 마다. 위와 같은 특성을 일일이 하나씩 만들어 주어야 한다면 굉장히 번거로울 것이다. 그래서 C++에서는 이러한 부분을 간단하게 하기 위해서 상속이라는 개념을 만들었다.


#include <iostream>
#include <cstring>
using namespace std;


class Car    //
조상클래스
{
public:
  char color[100];
  int Tire;
  int Eng;
  int Handle;
public:
  void print()
  {
    cout<<"
타이어수 : "<<Tire<<색상 : "<<color<<endl;
  }
};

class Ray:public Car
{
};// 
상속받았기 때문에 별다른 내용이 없어도 

//클래스 생성이되며 Warning 없음
class Tico:public Car
{
};

int main()
{
  Ray myCar1;
  Tico myCar2;

  myCar1.Tire=1;
  myCar2.Tire=4;
  
  strcpy(myCar1.color,"Pink");
  strcpy(myCar2.color,"Red");
  
//  cout<<"MyCar 1(Ray) - 
타이어수 : "

//<<myCar1.Tire<<색상 : "<<myCar1.color<<endl;
//  cout<<"MyCar 2(Tico) - 
타이어수 : "

//<<myCar2.Tire<<색상 : "<<myCar2.color<<endl;
  cout<<"Ray : ";
  myCar1.print();
  cout<<"Tico : ";
  myCar2.print();
}

 

상속 연산자  " : " 사용

왼쪽의 소스코드를 보면 쉽게 이해하겠지만

번거롭게 여러개의 클래스에 각각 공통되는 속성을 일일이 만들필요가 없다.

기본적으로 공통되는 속성은 조상클래스라는 Car에서 선언해주고 나머지 상속받는 클래스는 공통변수를 제외한 변수만 선언해주면된다.


c++에서는 이러한 객체지향이라는 특성때문에 클래스에 대한 상속개념까지 아주쉽게 표현해두었다.

 

. JAVA를 시작해보자!

인터넷에서 jdk를 다운받아서 설치하면 Program File\Java에 다음과 같은 디렉토리가 생성된다.


간단한 설명을 듣고 이제 환경변수를 설정하러 가자. 이전에 했듯이 아래의 그림처럼 주소를 복사해서 붙여준다.

완성되었다면 이제 간단한 소스코드를 작성해보자.

 


class smart
{
  public static void main(String[] args)  // public
하는 이유는 클래스안에 들어가있으므로
  {        // 
접근허가를 해주어야하며 static 생성하지 않아도 존재해야하므로..
    System.out.print("Hello World\n");
    return;
  }
};

 

참고로 컴파일은 javac라는 명령어는 컴파일이면 실행은 java 파일명이 된다.


≫ 위의 소스코드를 보면 C++과 흡사한면이 있다. 그 이유는 두 개의 언어 모두 객체지향 언어이기 때문이다.

하지만 C++ C를 객체지향으로 업그레이드 한 것이라 볼 수 있고 JAVA는 만들 때부터 객체지향으로 만들었다.

따라서 생성부터 main까지 객체 즉 클래스로 만들어준다.

 

소스코드를 보면 public static void main으로 main static을 붙여주는 이유는 생성하지 않아도 존재해야하는 것이기 때문이다.

아래는 간단한 JAVA의 프린트 문이다.

 

《오후수업 – Serial Communication

1. 우리가 이전까지 통신을 연결해서 메시지를 보내면 1 byte 즉 한글자 단위로 문자가 전송되었다.

이제는 지워지지 않고 문자열을 전송하고자 한다. 아래와 같이 수정해주면 된다.

if(0 != dwRead)
{
  //SetWindowText(hEdit, buff);
  SendMessage(hEdit,EM_REPLACESEL,(WPARAM)TRUE,(LPARAM)buff);
}

 

2. 이번에는 버튼을 만들어서 Edit Box에 있는 전달된 데이터를 지워주는 기능을 추가해보자. 먼저 아래의 소스코드를 작성해서 버튼을 만들어주자.

CreateWindow(TEXT("button"),TEXT("Clear"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,130,10,50,25,hWnd,(HMENU)0,g_hInst,NULL);

이제 만든 버튼을 통해서 해당버튼이 눌러주었을 때 동작하는 기능을 추가해주자.

case 0:
  SetDigitemTest(hWnd,1,NULL);
  MessageBox(hMain, TEXT("
지우기 성공"), TEXT("알림"), MB_OK);
  //SetWindowText(hEdit, " ");
  break;

버튼의 아이디가 0으로 설정했기 때문에 WM_COMMAND case문 아이디를 0으로 해주고 간단히 지워졌다는 메시지를 하나 넣어준 뒤 SetDigitemTest라는 Edit박스안의 내용을 Clear해주는 함수를 사용해주면 간단하다.

  

 

3. 세번째 실습은 WinAPI에서 키보드 버튼 1을 입력 하면 시리얼PAD에 데이터를 전송해보자.

static unsigned char ucHostComm[2][13= {
      {0x0D, 0x000x710x000x3F, 0x000x000x000x0A, 0x000x000xB20x58},
      {0x0D, 0x000x710x000x300x000x000x000x0A, 0x000x000x460x58}
};

전송하고자하는 데이터를 2차원 배열로 선언했다

 

case WM_CHAR:  // 알파벳 키에 반응

  if(FALSE == bPortOnOff)
  {
    return 0;
  }
  if('1' != (TCHAR)wParam)
  {
    return 0;
  }    
  if(0 == WriteFile(hComm, ucHostComm[(TCHAR)wParam - '1'], ucHostComm[(TCHAR)wParam - '1'][0], &dwWritten, 0))
  {    
    MessageBox(hMain, TEXT("
쓰기 에러"), TEXT("알림"), MB_OK);      
  }
  return 0;

3번째 if문에서 WriteFile로 입력해있는 배열의 데이터를 전송하는 방식이다.

 

실행결과:




이상입니다 !!

728x90