-
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);
}
}
}
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20141015 (C++ class 내에 const static, mutable, 상속, ) (0) 2014.10.15 20141014 (C++ class내에 const, friend, static, 시리얼 통신 winapi) (0) 2014.10.14 20141010 (C++ this) (0) 2014.10.10 20141008 (C++ 맴버 이니셜라이저) (0) 2014.10.08 20141007 (C++ 정보은닉, 캡슐화, 생성자, 소멸자, 비디오처리) (0) 2014.10.07