Virtual Friend Function
2015-12-21 13:51
204 查看
一般而言,友元作为一种紧耦合的设计,被视作类的一部分。一个经典的应用就是关于类的序列化和反序列化。
问题是当在一个继承结构里面,每个类都需要这么一个序列化(反序列化)过程的时候,每次重新写一个友元函数实在是繁琐。
但是友元函数又不是类的成员函数,不能定义成虚函数。于是在C++提供了这样一种语法支持:在友元函数里面调用虚函数,使得
它能够呈现出多态特性:
这样,我们只要重载成员函数printOn,就能直接使得我们定义的派生类具备了序列化(反序列化)的能力。
问题是这里为什么不直接将printOn定义成public的,然后直接用它呢?
我能理解出的一个优点就是统一性,所有类都去定义这样的序列化操作符,比起各自设计不同的成员函数要强。
class A { friend ostream& operator<<(ostream& os, const A& a); private: int i; } ostream& operator<<(ostream& os, const A& a) { return os << a.i; }
问题是当在一个继承结构里面,每个类都需要这么一个序列化(反序列化)过程的时候,每次重新写一个友元函数实在是繁琐。
但是友元函数又不是类的成员函数,不能定义成虚函数。于是在C++提供了这样一种语法支持:在友元函数里面调用虚函数,使得
它能够呈现出多态特性:
class Base { public: friend std::ostream& operator<< (std::ostream& o, const Base& b); // ... protected: virtual void printOn(std::ostream& o) const = 0; // Or plain virtual; see below }; inline std::ostream& operator<< (std::ostream& o, const Base& b) { b.printOn(o); return o; } class Derived : public Base { public: // ... protected: virtual void printOn(std::ostream& o) const; }; void Derived::printOn(std::ostream& o) const { // ... }
这样,我们只要重载成员函数printOn,就能直接使得我们定义的派生类具备了序列化(反序列化)的能力。
问题是这里为什么不直接将printOn定义成public的,然后直接用它呢?
我能理解出的一个优点就是统一性,所有类都去定义这样的序列化操作符,比起各自设计不同的成员函数要强。
相关文章推荐
- IdHttp 资料
- Kettle使用资源库日志信息配置
- 自己指定的学习路线
- 了解负载均衡 会话保持 session同步(转)
- DT大数据梦工厂免费实战大数据视频全集
- Builder设计模式设置自定义Dialog
- SATA硬盘的数据和电源接口定义
- Kafka设计解析(三):Kafka High Availability (下)
- 微信支付-小小工程狮的成长之路
- 日经春秋 20151221
- 文件缓存
- BZOJ 1509: [NOI2003]逃学的小孩( 树形dp )
- oracle 查看后台正在执行的脚本
- jsp的三种自定义标签 写法示例
- swfobject简单封装
- 关于android:clickable="false"失效的问题
- 关于Android中工作者线程的思考
- 顺序右移数组元素(第0届第5题)
- 天声人語 20151221 立憲か、非立憲か
- 【转载】 Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载