다음을 통해 공유


Serialization: Serialize 가능한 클래스 만들기

클래스를 직렬화하려면 5개의 기본 단계가 필요합니다. 아래에 나열되어 있으며 다음 섹션에 설명되어 있습니다.

  1. CObject (또는 파생된 일부 클래스)에서 CObject클래스를 파생합니다.

  2. Serialize 멤버 함수를 재정의합니다.

  3. 클래스 선언에서 DECLARE_SERIAL 매크로 사용

  4. 인수를 사용하지 않는 생성자 정의

  5. 클래스의 구현 파일 에서 IMPLEMENT_SERIAL 매크로 사용

CArchive 및 << 연산자를 >> 통하지 않고 직접 호출 Serialize 하는 경우 마지막 세 단계는 serialization에 필요하지 않습니다.

CObject에서 클래스 파생

기본 serialization 프로토콜 및 기능은 클래스에 CObject 정의됩니다. 다음 클래스 선언에 CObject 표시된 대로 클래스를 파생(또는 파생된 클래스CPerson에서CObject)하여 serialization 프로토콜 및 기능에 CObject액세스할 수 있습니다.

Serialize 멤버 함수 재정의

Serialize 클래스에 CObject 정의된 멤버 함수는 개체의 현재 상태를 캡처하는 데 필요한 데이터를 실제로 직렬화합니다. 함수에는 Serialize CArchive 개체 데이터를 읽고 쓰는 데 사용하는 인수가 있습니다. CArchive 개체에는 저장(데이터 작성) 또는 로드(데이터 읽기) 여부를 Serialize 나타내는 멤버 함수IsStoring가 있습니다. 안내선으로 결과를 IsStoring 사용하여 개체의 데이터를 삽입 연산자()로 개체에 CArchive 삽입하거나 추출 연산자(<<>>)를 사용하여 데이터를 추출합니다.

형식 CStringWORD의 두 개의 새 멤버 변수에서 CObject 파생되고 있는 클래스를 고려합니다. 다음 클래스 선언 조각은 재정의된 Serialize 멤버 함수에 대한 새 멤버 변수 및 선언을 보여 줍니다.

class CPerson : public CObject
{
public:
   DECLARE_SERIAL(CPerson)
   // empty constructor is necessary
   CPerson();
   virtual ~CPerson();

   CString m_name;
   WORD   m_number;

   void Serialize(CArchive& archive);
};

Serialize 멤버 함수를 재정의하려면

  1. 기본 클래스 버전을 호출하여 개체의 Serialize 상속된 부분이 serialize되는지 확인합니다.

  2. 클래스와 관련된 멤버 변수를 삽입하거나 추출합니다.

    삽입 및 추출 연산자는 보관 클래스와 상호 작용하여 데이터를 읽고 씁니다. 다음 예제에서는 위에 선언된 클래스에 대해 구현 Serialize 하는 CPerson 방법을 보여줍니다.

    void CPerson::Serialize(CArchive& archive)
    {
       // call base class function first
       // base class is CObject in this case
       CObject::Serialize(archive);
    
       // now do the stuff for our specific class
       if (archive.IsStoring())
          archive << m_name << m_number;
       else
          archive >> m_name >> m_number;
    }
    

CArchive::ReadCArchive::Write 멤버 함수를 사용하여 많은 양의 형식화되지 않은 데이터를 읽고 쓸 수도 있습니다.

DECLARE_SERIAL 매크로 사용

DECLARE_SERIAL 매크로는 다음과 같이 serialization을 지원하는 클래스 선언에 필요합니다.

class CPerson : public CObject
{
public:
   DECLARE_SERIAL(CPerson)

인수가 없는 생성자 정의

MFC에는 개체가 역직렬화될 때(디스크에서 로드됨) 개체를 다시 만들 때 기본 생성자가 필요합니다. 역직렬화 프로세스는 개체를 다시 만드는 데 필요한 값으로 모든 멤버 변수를 채웁니다.

이 생성자는 public, protected 또는 private으로 선언할 수 있습니다. 보호되거나 비공개로 설정하면 serialization 함수에서만 사용할 수 있는지 확인하는 데 도움이 됩니다. 생성자는 필요한 경우 삭제할 수 있는 상태로 개체를 배치해야 합니다.

참고 항목

DECLARE_SERIAL 및 IMPLEMENT_SERIAL 매크로를 사용하는 클래스에서 인수가 없는 생성자를 정의하는 것을 잊어버린 경우 IMPLEMENT_SERIAL 매크로가 사용되는 줄에 "사용할 수 있는 기본 생성자 없음" 컴파일러 경고가 표시됩니다.

구현 파일에서 IMPLEMENT_SERIAL 매크로 사용

IMPLEMENT_SERIAL 매크로는 serialize 가능한 클래스 CObject를 파생할 때 필요한 다양한 함수를 정의하는 데 사용됩니다. 구현 파일()에서 이 매크로를 사용합니다. 클래스에 대한 CPP)입니다. 매크로의 처음 두 인수는 클래스의 이름과 해당 직계 기본 클래스의 이름입니다.

이 매크로의 세 번째 인수는 스키마 번호입니다. 스키마 번호는 기본적으로 클래스의 개체에 대한 버전 번호입니다. 스키마 번호에 대해 0보다 크거나 같은 정수를 사용합니다. (이 스키마 번호를 데이터베이스 용어와 혼동하지 마세요.)

MFC serialization 코드는 개체를 메모리로 읽을 때 스키마 번호를 검사. 디스크에 있는 개체의 스키마 번호가 메모리에 있는 클래스의 스키마 번호와 일치하지 않으면 라이브러리가 throw CArchiveException되어 프로그램이 잘못된 버전의 개체를 읽지 못하게 됩니다.

멤버 함수가 여러 버전, 즉 애플리케이션의 다른 버전으로 작성된 파일을 읽을 수 있도록 하려면 Serialize IMPLEMENT_SERIAL 매크로에 대한 인수로 VERSIONABLE_SCHEMA 값을 사용할 수 있습니다. 사용 정보 및 예제는 클래스의 멤버 함수를 GetObjectSchema 참조하세요 CArchive.

다음 예제에서는 파생된 CObject클래스CPerson에 IMPLEMENT_SERIAL 사용하는 방법을 보여줍니다.

IMPLEMENT_SERIAL(CPerson, CObject, 1)

serialize할 수 있는 클래스가 있으면 Serialization: 개체 직렬화 문서에서 설명한 대로 클래스의 개체를 serialize할 수 있습니다.

참고 항목

직렬화