设为首页 加入收藏

TOP

17.3.3 序列化元素类(1)
2013-10-07 16:13:07 来源: 作者: 【 】 浏览:67
Tags:17.3.3 序列化 元素

17.3.3  序列化元素类(1)

所有形状类都是可序列化的,因为它们都派生于其基类CElement,而CElement又派生于CObject。把CObject指定为CElement的基类的原因仅仅是为了获得对序列化的支持。确保实际上为每个形状类定义了默认构造函数。反序列化过程要求定义此构造函数。

现在可以为每个形状类添加对序列化的支持,这要在类定义和实现中添加适当的宏,然后给每个类的Serialize()函数成员添加代码,以序列化该函数的数据成员。可以首先从基类CElement开始,其中需要对类定义做如下修改:
 

  1. class CElement: public CObject  
  2. {  
  3. DECLARE_SERIAL(CElement)  
  4. protected:  
  5. CPoint m_StartPoint;                                                                                                    // Element position  
  6. int m_PenWidth;                                                                                                                 // Pen width  
  7. COLORREF m_Color;                                                                                                           // Color of an element  
  8. CRect m_EnclosingRect;                                                                                          // Rectangle enclosing an element  
  9. public:  
  10. virtual ~CElement();  
  11. virtual void Draw(CDC* pDC, std::shared_ptr<CElement> pElement=nullptr) {}  
  12. virtual void Move(const CSize& aSize){}                                 // Move an element  
  13. virtual void Serialize(CArchive& ar) override;          // Serialize object  
  14. // Get the element enclosing rectangle  
  15. const CRect GetEnclosingRect() const  
  16. {  
  17. return m_EnclosingRect;  
  18. }  
  19. protected:  
  20. // Constructors protected so they cannot be called outside the class  
  21. CElement();  
  22. CElement(const CPoint& start, COLORREF color, int penWidth = 1);  
  23. // Create a pen  
  24. void CreatePen(CPen& aPen, std::shared_ptr<CElement> pElement)  
  25. {  
  26. if(!aPen.CreatePen(PS_SOLID, m_PenWidth,  
  27. (this == pElement.get())   SELECT_COLOR : m_Color))  
  28. {  
  29. // Pen creation failed  
  30. AfxMessageBox(_T(“Pen creation failed.”), MB_OK);  
  31. AfxAbort();  
  32. }  
  33. }  
  34. };  

其中添加了DECLARE_SERIAL()宏以及虚函数Serialize()的声明。Application Wizard已经创建了一个默认的构造函数,在这个类中把它修改成了protected类型,只要它显式地出现在类定义中,它的访问规范是什么就无关紧要。它可以是public、protected或private类型,但是序列化仍然有效。如果忘记在一个类中包括默认构造函数,那么在编译IMPLEMENT_SERIAL()宏时,将出现一条错误消息。

应当为每个派生类CLine、CRectangle、CCircle、CCurve和CText都添加DECLARE_SERIAL()宏,其参数为相关类名。另外,还应当把Serialize()函数的重载声明添加为每个类的public成员。

在文件Elements.cpp中,必须在开始处添加下列宏:

  1. IMPLEMENT_SERIAL(CElement, CObject, VERSION_NUMBER) 

在文件Element.h的其他静态常量的后面,添加下列行,可以定义静态常量VERSION_NUMBER:
 

  1. static const UINT VERSION_NUMBER = 1001;                    // Version number for serialization 

然后在为其他形状类的.cpp文件中添加这个宏时,就可以使用该常量。例如对于CLine类,应当添加下列行:
 

  1. IMPLEMENT_SERIAL(CLine, CElement, VERSION_NUMBER) 

对于其他形状类也可以采用类似的方法。在修改与文档有关的类时,只需要在文件Element.h中修改VERSION_NUMBER的定义,这个新版本号在所有的Serialize()函数中都将适用。

形状类中的Serialize()函数

现在可以针对每个形状类实现Serialize()成员函数。首先从CElement类开始,在Elements.cpp中添加如下定义:
 

  1. void CElement::Serialize(CArchive& ar)  
  2. {  
  3. CObject::Serialize(ar);                                                     // Call the base class function  
  4. if (ar.IsStoring())  
  5. { // Writing to the file  
  6. ar << m_StartPoint                                                              // Element position  
  7. << m_PenWidth                                                                   // The pen width  
  8. << m_Color                                                                              // The element color  
  9. << m_EnclosingRect;                                             // The enclosing rectangle  
  10. }  
  11. else  
  12. { // Reading from the file  
  13. ar >> m_StartPoint                                                                  // Element position  
  14. >> m_PenWidth                                                                       // The pen width  
  15. >> m_Color                                                                                  // The element color  
  16. >> m_EnclosingRect;                                                 // The enclosing rectangle  
  17. }  
  18. }  

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇17.3.2 序列化文档 下一篇17.3.3 序列化元素类(2)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·数据库:推荐几款 Re (2025-12-25 12:17:11)
·如何最简单、通俗地 (2025-12-25 12:17:09)
·什么是Redis?为什么 (2025-12-25 12:17:06)
·对于一个想入坑Linux (2025-12-25 11:49:07)
·Linux 怎么读? (2025-12-25 11:49:04)