직렬화
직렬화
도큐먼트 클래스는 COnject 를 상속받고 있어 도큐먼트 클래스의 멤버 변수의 값을 파일에 저장하고 불러올 수 있다.
각 멤버의 값이 변경되었으면 도큐먼트 클래스의 SetModifyFlag() 멤버 함수를 호출하면 되고, 이것은 변경된 데이터를 저장하지 않고 프로그램을 종료할때 저장할 것인지 물어보게 해준다.
기본 SDI 프로젝트는 파일에 저장할 값을 저장 메뉴를 클릭하면 지정한 파일로 데이터를 저장할 수 있으므로 Serialize() 멤머 함수에서 저장할 변수를 지정하면된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
void CTestSerializeDoc::Serialize(CArchive& ar)
{
// m_ElementList.Serialize(ar);
if (ar.IsStoring()) // 저장
{
// TODO: 여기에 저장 코드를 추가합니다.
ar << m_Color << m_PenWidth << m_DocSize;
}
else // 읽기
{
// TODO: 여기에 로딩 코드를 추가합니다.
ar >> m_Color >> m_PenWidth >> m_DocSize;
}
} |
cs |
Test.123 파일에 저장된 값을 불러오는 코드는 아래와 같다.
Test.123 파일을 열고, 8행과 같이 CArchive 인스턴스인 ar에 파일을 지정하고, load 옵션을 지정해서 인스턴스를 만든다. 그런다음 도큐먼트의 Serialize() 함수 인수에 ar 을 넘겨주면 해당 파일에서 값을 읽어온다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
void CTestSerializeView::OnTest32772()// 불러오기
{
// TODO: 여기에 명령 처리기 코드를 추가합니다.
CTestSerializeDoc* pDoc = GetDocument();
CFile file;
if (file.Open(_T("Test.123"), CFile::modeRead))
{
CArchive ar(&file, CArchive::load);
pDoc->Serialize(ar);
}
COLORREF Color = pDoc->m_Color;
UINT Element = pDoc->m_Element;
int PenWidth = pDoc->m_PenWidth;
CSize DocSize = pDoc->m_DocSize;
} |
cs |
만약, 도큐먼트 클래스 외 다른 클래스의 값을 저장하려면 아래와 같이 코드를 직접 추가해야 한다.
1. CObject 를 상속 받아야 한다.
2. DECLARE_SERIAL() 매크로 추가
3. virtual void Serialize(CArchive& ar); 가상함수 재정의
4. IMPLEMENT_SERIAL() 매크로 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 |
#define _VERSION_NUMBER 1
class CElement : public CObject
{
DECLARE_SERIAL(CElement)
protected:
COLORREF m_Color;
CRect m_EnCloseingRect;
int m_Pen;
public:
virtual ~CElement() {};
virtual void Serialize(CArchive& ar);
protected:
CElement() {};
};
IMPLEMENT_SERIAL(CElement, CObject, _VERSION_NUMBER);
void CElement::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if (ar.IsStoring())
ar << m_Color << m_EnCloseingRect << m_Pen;
else
ar >> m_Color >> m_EnCloseingRect >> m_Pen;
} |
cs |
직렬화 가능한 변수 타입
bool, float, double, BYTE, char, wchar_t, int, short, LONG, long, LONGLONG, ULONGLONG, WORD, UINT, DWORD, CObject*, CString, SIZE, CSize, POINT, CPoint, RECT, CRect
이외의 데이터 타입인 CTypedPtrList 와 같은 템플릿을 직렬화 하려면, CObject를 사용하여 컬렉션 템플릿으로 부터 정의하면 된다.
예) CTypedPtrList<CObject, CElement*> m_ElementList;