CArchive类体内的友元操作符重载函数的研究
来源:互联网 发布:淘宝首页优惠券代码 编辑:程序博客网 时间:2024/06/05 19:11
为什么把CArchive类体内的三个操作符重载函数声明为友元的,而不是类成员函数呢?
对于CString CRect CSize CPoint 类它们有自己对于CArchive的<<和>>操作符重载函数并将这些操作符重载函数声明为全局友元函数,原因是如果操作符重载函数是类成员函数的话,那么对于2元操作符来说,左操作数默认为该类对象,参照这些函数的定义我们发现左操作数类型都不是该类对象,所以这些操作重载函数不能是类成员函数,必须是全局函数了,在类体内对一个函数加上友元关键字就表示此函数不是类成员函数,而是一个全局函数,所以在这里声明友元函数的意思就是告诉编译器和我们这个函数不是类成员函数,而是一个全局函数.这是第一个原因,第二个原因就是我马上要提到的CArchive类体内的三个操作符重载函数为什么也必须是友元的了。
查看CArchive的类定义,我们发现对于普通数据类型的操作符重载函数,CArchive是声明为类成员函数的,但是还是有三个操作符重载函数是友元的,所以这三个函数是全局函数,按照我刚刚的道理来说,这里左操作数类型就是CArchive对象引用,为什么要把这三个函数声明为友元的呢,答案是为了实现函数重载,注意这里是函数重载不是操作符重载,这三个友元操作符重载函数的声明如下:
friend CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb);
friend CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb);
friend CArchive& AFXAPI operator>>(CArchive& ar, const CObject*& pOb);
都是全局域的函数,需要和什么函数构成重载呢?答案是和前面提到的CString、CRect、CSize、CPoint类,它们都针对CArchive 的<< 和>> 自己设计了一套函数方法如下:
friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string);
friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string)
CArchive& AFXAPI operator<<(CArchive& ar, SIZE size);
CArchive& AFXAPI operator<<(CArchive& ar, POINT point);
CArchive& AFXAPI operator<<(CArchive& ar, const RECT& rect);
CArchive& AFXAPI operator>>(CArchive& ar, SIZE& size);
CArchive& AFXAPI operator>>(CArchive& ar, POINT& point);
CArchive& AFXAPI operator>>(CArchive& ar, RECT& rect);
参考书---深入浅出MFC 2e 第8章 Document-View深入讨论(整章)
---C++ Primer 3rd 第15章 15.1节 操作符重载 和 15.2节 友元
关于MFC中的DECLARE_SERIAL宏展开后的
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);操作符重载函数声明
和 IMPLEMENT_SERIAL宏展开的
CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) /
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); /
return ar; } /操作符重载函数的定义
我的测试结果是这个操作符重载函数至少在深入浅出MFC 2e Document-View深入讨论那章中的程序举例中根本不会被调用
被调用的是
AFX_INLINE CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb)
{ pOb = ar.ReadObject(NULL); return ar; }
这个CArchive 内声明为友元全局操作符重载函数
可以做如下测试把这对宏改为如下方式:并放置与头文件StdAfx.h中(注意这对宏我加字母串最后我加了'A')
来和MFC定义的这对宏用于区分。测试程序没有任何问题,读取和写入文件都没有错误
同时从下面测试更改也看的出 和 _DECLARE_DYNCREATE那对宏比较
IMPLEMENT_SERIALA在这里唯一与_DECLARE_DYNCREATE那对宏不同的就是指定串型类的版本号
放入了CRuntimeClass结构体成员变量UINT m_wSchema中
#define IMPLEMENT_SERIALA(class_name, base_class_name, wSchema) /
CObject* PASCAL class_name::CreateObject() /
{ return new class_name; } /
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, /
class_name::CreateObject) /
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); /
#define DECLARE_SERIALA(class_name) /
_DECLARE_DYNCREATE(class_name) /
对于CString CRect CSize CPoint 类它们有自己对于CArchive的<<和>>操作符重载函数并将这些操作符重载函数声明为全局友元函数,原因是如果操作符重载函数是类成员函数的话,那么对于2元操作符来说,左操作数默认为该类对象,参照这些函数的定义我们发现左操作数类型都不是该类对象,所以这些操作重载函数不能是类成员函数,必须是全局函数了,在类体内对一个函数加上友元关键字就表示此函数不是类成员函数,而是一个全局函数,所以在这里声明友元函数的意思就是告诉编译器和我们这个函数不是类成员函数,而是一个全局函数.这是第一个原因,第二个原因就是我马上要提到的CArchive类体内的三个操作符重载函数为什么也必须是友元的了。
查看CArchive的类定义,我们发现对于普通数据类型的操作符重载函数,CArchive是声明为类成员函数的,但是还是有三个操作符重载函数是友元的,所以这三个函数是全局函数,按照我刚刚的道理来说,这里左操作数类型就是CArchive对象引用,为什么要把这三个函数声明为友元的呢,答案是为了实现函数重载,注意这里是函数重载不是操作符重载,这三个友元操作符重载函数的声明如下:
friend CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb);
friend CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb);
friend CArchive& AFXAPI operator>>(CArchive& ar, const CObject*& pOb);
都是全局域的函数,需要和什么函数构成重载呢?答案是和前面提到的CString、CRect、CSize、CPoint类,它们都针对CArchive 的<< 和>> 自己设计了一套函数方法如下:
friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string);
friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string)
CArchive& AFXAPI operator<<(CArchive& ar, SIZE size);
CArchive& AFXAPI operator<<(CArchive& ar, POINT point);
CArchive& AFXAPI operator<<(CArchive& ar, const RECT& rect);
CArchive& AFXAPI operator>>(CArchive& ar, SIZE& size);
CArchive& AFXAPI operator>>(CArchive& ar, POINT& point);
CArchive& AFXAPI operator>>(CArchive& ar, RECT& rect);
参考书---深入浅出MFC 2e 第8章 Document-View深入讨论(整章)
---C++ Primer 3rd 第15章 15.1节 操作符重载 和 15.2节 友元
关于MFC中的DECLARE_SERIAL宏展开后的
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);操作符重载函数声明
和 IMPLEMENT_SERIAL宏展开的
CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) /
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); /
return ar; } /操作符重载函数的定义
我的测试结果是这个操作符重载函数至少在深入浅出MFC 2e Document-View深入讨论那章中的程序举例中根本不会被调用
被调用的是
AFX_INLINE CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb)
{ pOb = ar.ReadObject(NULL); return ar; }
这个CArchive 内声明为友元全局操作符重载函数
可以做如下测试把这对宏改为如下方式:并放置与头文件StdAfx.h中(注意这对宏我加字母串最后我加了'A')
来和MFC定义的这对宏用于区分。测试程序没有任何问题,读取和写入文件都没有错误
同时从下面测试更改也看的出 和 _DECLARE_DYNCREATE那对宏比较
IMPLEMENT_SERIALA在这里唯一与_DECLARE_DYNCREATE那对宏不同的就是指定串型类的版本号
放入了CRuntimeClass结构体成员变量UINT m_wSchema中
#define IMPLEMENT_SERIALA(class_name, base_class_name, wSchema) /
CObject* PASCAL class_name::CreateObject() /
{ return new class_name; } /
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, /
class_name::CreateObject) /
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); /
#define DECLARE_SERIALA(class_name) /
_DECLARE_DYNCREATE(class_name) /
- CArchive类体内的友元操作符重载函数的研究
- 类的操作符重载及友元函数
- 友元函数实现操作符重载的应用场景-友元函数实现左移右移操作符重载
- 友元函数与类重载运算操作符的异同
- 重载为类的友元函数
- 处理虚数类 运算符的重载 友元函数
- 复数类的运算符重载(友元函数)
- 多态性:运算符重载为类的友元函数
- c++ 类的使用 友元函数 重载运算符
- 操作符重载与友元函数
- 操作符重载及友元函数
- 模板类与非模板类中将重载操作符函数作为友元函数的区别
- 类,友元函数 ,重载操作符(+, +=)
- C++学习笔记(七)--操作符重载 友元函数 类的继承 访问控释protected
- 操作符重载和友元的关系
- 复数的友元函数重载
- 运算符重载函数作为类成员函数与友元函数的区别
- 操作符重载为成员函数还是友元函数?
- Oracle 连接远程数据库及远程执行DDL操作--原创
- OLTP的概念、集成与开发系统
- 戏说项目管理
- gdb调试内存错误
- 21天学通C语言第三天---存储类型
- CArchive类体内的友元操作符重载函数的研究
- 快乐式项目管理
- 烦烦烦.......
- 找工作的经验
- 用GDB调试程序
- 看到我的就要毕业的学生,我的心里很复杂
- 阿D常用注入命令收集整理
- 三十岁以前的生活
- 使用 LumiSoft.Net.POP3.Client 接收邮件心得