ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20141013 (C++ 복사 생성자, 시리얼 통신 winapi)
    부산IT학원/스마트컨트롤러 2014. 10. 13. 17:35

    156일차






    -----------

    C++

    -----------



    ------- 복사 생성자

    예제를 보자.


    소스)

    #include <iostream>

    #include <cstring>


    using namespace std;


    class smart

    {

    public:

    char * p;


    public:

    smart()

    {

    cout << "D생성자" << endl;

    p = new char[3];

    strcpy(p, "Hi");

    }


    smart(const smart & r) // 복사 생성자, 복사 받는 값은 변경하지 않으니

    { // 보통 앞에 const를 붙인다

    p = new char[3];

    strcpy(p, r.p);

    cout << p << "복사 생성자" << endl;

    }


    ~smart()

    {

    cout << "~소멸자" << endl;

    delete []p;

    }


    smart test()

    {

    smart t;

    *(t.p) = 'X';

    return t;

    }

    };


    int main()

    {

    smart obj1; // 디폴트 생성자 호출

    smart obj2; // 디폴트 생성자 호출


    // obj2 = obj1; // 대입 연산자 호출


    *(obj2.p) = 'L';


    smart obj3 = obj2; // 복사 생성자 호출

    smart obj4(obj3); // 복사 생성자 호출


    smart obj5 = obj4.test();


    cout << "this is test" << endl;


    return 0;

    }


    결과





    위 처럼 생성자인데 바로 다른 값을 넣어주는 것을 복사 생성자라 한다.

    이것을 선언해 주지 않을시 기본값으로 만들어져 있다.


    만약 위 소스에서

    smart(const smart & r) // 복사 생성자, 복사 받는 값은 변경하지 않으니

    { // 보통 앞에 const를 붙인다

    // p = new char[3];

    // strcpy(p, r.p);

    cout << p << "복사 생성자" << endl;

    }

    해버리면 오류다ㅋ


    http://wowcat.tistory.com/1946








    ------- explicit

    복사 생성자를 사용할 때 묵시적 변환이 일어나서

    복사 생성자가 호출되는 경우가 있는데, 무슨 말이냐 하면...


    smart obj1 = obj2;      =>      smart obj1(obj2);


    이렇게 묵시적으로 바뀐다.

    여기서 smart obj1 = obj2; 형태가 맘에 들지 않으면 복사 생성자의 묵시적 호출을

    허용하지 않을 수 있는데, 이때 사용하는 키워드가 explicit 이다.


    예제)

    class smart

    {

    public:

    smart()

    {

    cout << "디폴트 생성자" << endl;

    }

    explicit smart(smart n)

    {

    cout << "복사 생성자" << endl;

    }

    };


    int main()

    {

    smart obj1;


    smart obj2(obj1);     // ok!

    smart obj3 = obj1;    // error!


    return 0;

    }





    ------- 임시 객체

    실제로 쓰지는 않고 임시 객체를 통해서

    생성자와 소멸자가 사라지는 시간을 확인하는 소스이다.


    예제)

    #include <iostream>


    using namespace std;


    class Temporary

    {

    private:

    int num;

    public:

    Temporary(int n) : num(n)

    {

    cout<<"create obj: "<<num<<endl;

    }

    ~Temporary()

    {

    cout<<"destroy obj: "<<num<<endl;  

    }

    void ShowTempInfo()

    {

    cout<<"My num is "<<num<<endl;

    }

    };


    int main(void)

    {

    Temporary(100);

    cout<<"********** after make!"<<endl<<endl;


    Temporary(200).ShowTempInfo();

    cout<<"********** after make!"<<endl<<endl;


    const Temporary &ref=Temporary(300);

    cout<<"********** end of main!"<<endl<<endl;

    return 0;

    }


    결과













    ---------------------

    Winapi 시리얼 통신

    ---------------------



    ------- 시리얼 통신

    소스를 짜기 앞서,


    사용할 포트를 설정해 줘야한다. Virtual Serial Ports Driver라는 프로그램으로

    8번과 9번을 연결해 놓았다.


    하이퍼 터미널로 9번을 열었다면, 작성할 소스는 8번을 열어야 한다.


    소스)

    #include <windows.h>

    #include <stdio.h>


    int main()

    {

    u_char caString[10] = "하이~";

    DWORD dwWritten;

    DCB sPState;

    HANDLE hComm = CreateFile("COM8", GENERIC_READ | GENERIC_WRITE

    , 0, NULL, OPEN_EXISTING

    , FILE_ATTRIBUTE_NORMAL, 0);


    if(INVALID_HANDLE_VALUE == hComm)

    {

    printf("포트 열 수 없음\n");

    return 0;

    }


    if(0 == SetupComm(hComm, 4096, 3096))

    {

    printf("버퍼 설정 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    if(0 == PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))

    {

    printf("버퍼 초기화 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    sPState.DCBlength = sizeof(sPState);


    if(0 == GetCommState(hComm, &sPState))

    {

    printf("시리얼 상태 읽기 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    sPState.BaudRate = CBR_38400;

    sPState.ByteSize = 8;

    sPState.Parity = EVENPARITY;

    sPState.StopBits = ONESTOPBIT;


    if(0 == SetCommState(hComm, &sPState))

    {

    printf("시리얼 상태 설정 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    if(0 == ReadFile(hComm, caString, sizeof(caString), &dwWritten, 0))

    //if(0 == WriteFile(hComm, caString, sizeof(caString), &dwWritten, 0))

    {

    printf("쓰기 에러\n");

    }

    else

    {

    // printf("쓰기 성공\n");

    printf("읽기 성공\n");

    printf("[%s]\n", caString);

    }


    CloseHandle(hComm);


    return 0;

    }







    ------- 스레드 + 시리얼 통신

    소스)

    #include <windows.h>

    #include <stdio.h>


    DWORD WINAPI Thread_Read(LPVOID);


    HANDLE hComm;


    int main()

    {

    u_char caString[10] = "하이~";

    //char buf;

    DWORD dwWritten;

    DCB sPState;

    COMMTIMEOUTS cTime;

    DWORD ThreadID;

    HANDLE hThread;


    hComm = CreateFile("COM8", GENERIC_READ | GENERIC_WRITE

    , 0, NULL, OPEN_EXISTING

    , FILE_ATTRIBUTE_NORMAL, 0);


    if(INVALID_HANDLE_VALUE == hComm)

    {

    printf("포트 열 수 없음\n");

    return 0;

    }


    if(0 == SetupComm(hComm, 4096, 3096))

    {

    printf("버퍼 설정 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    if(0 == PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))

    {

    printf("버퍼 초기화 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    sPState.DCBlength = sizeof(sPState);


    if(0 == GetCommState(hComm, &sPState))

    {

    printf("시리얼 상태 읽기 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    sPState.BaudRate = CBR_38400;

    sPState.ByteSize = 8;

    sPState.Parity = EVENPARITY;

    sPState.StopBits = ONESTOPBIT;


    cTime.ReadIntervalTimeout = MAXDWORD; // 시간 설정, 블록킹 됐을시 기다리는 시간

    cTime.ReadTotalTimeoutMultiplier = 0; // 0은 무한 대기

    cTime.ReadTotalTimeoutConstant = 0;

    cTime.WriteTotalTimeoutMultiplier = 0; // 0은 무한 대기

    cTime.WriteTotalTimeoutConstant = 0;


    SetCommTimeouts(hComm, &cTime);


    if(0 == SetCommState(hComm, &sPState))

    {

    printf("시리얼 상태 설정 에러\n");

    CloseHandle(hComm);

    return 0;

    }


    hThread = CreateThread(NULL, 0, Thread_Read, NULL, 0, &ThreadID);


    while(1)

    {

    caString[0] = getch();

    if(0 == WriteFile(hComm, caString, 1, &dwWritten, 0))

    {

    printf("쓰기 에러\n");

    }

    else

    {

    printf("쓰기 성공\n");

    }

    }


    CloseHandle(hComm);


    return 0;

    }


    DWORD WINAPI Thread_Read(LPVOID NotUse)

    {

    char buf = 0;

    DWORD dwRead;


    while(1)

    {

    Sleep(100);

    ReadFile(hComm, &buf, 1, &dwRead, NULL);

    if(0 != dwRead)

    {

    printf("[%c] ", buf);

    }

    }

    }







Designed by Tistory.