Virtual Friend Function

一般而言,友元作为一种紧耦合的设计,被视作类的一部分。一个经典的应用就是关于类的序列化和反序列化。

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的,然后直接用它呢?

我能理解出的一个优点就是统一性,所有类都去定义这样的序列化操作符,比起各自设计不同的成员函数要强。

时间: 2024-10-10 11:47:49

Virtual Friend Function的相关文章

Virtual Member Functions &amp; Static Member Function

如果一个 normalize() 是一个 virtual member function, 那么以下的调用: ptr->normalize(); 将会被内部转化为: (*ptr->vptr[1])(ptr); 其中:vptr 表示由编译器生成的指针, 指向 virtual table, 它被安插在每一个声明有(或继承自) virtual functinos 的 class object 中. 事实上其名称也会被 mangled, 因为在一个复杂的 class 派生体系中, 可能存在多个 vpt

More Effective C++ 条款25 将constructor和non-member function虚化

1. Virtual constructor 原则上构造函数不能为虚:虚函数用于实现"因类型而异的行为",也就是根据指针或引用所绑定对象的动态类型而调用不同实体,但构造函数用于构造对象,在对象构造之前自然没有动态类型的概念,虚与非虚也就无从谈起.所谓的的virtual-constructor实际上是"仿virtual-constructor",它本质上不是constructor,但能够产生不同类型的对象,从而实现"virtual-constructor&q

virtual成员函数

一,虚函数一般实现模型:    每一个类只要含有虚函数,就会创建一个虚函数表,里面包含的虚函数的地址,每个类对象里面包含一个指针(vptr)指向这个虚函数表.(ps基于主流编译器的,标准并未规定)下面我们来测试一下: #include<iostream> using namespace std; class A { private: int va; //4 int vb; //4 }; class B { public: virtual void foo(){}; private: int v

【c++】Function语义学之成员函数调用方式

非静态成员函数 编译器内部已将member函数实体转换为对等的nonmember函数实体. 转化步骤: 1.改写函数原型以安插一个额外的参数到member function中,使class object可以调用该函数,该额外参数为this指针. 2.将函数中每一个对nonstatic data member的存取操作改为经由this指针来存取 3.对函数名称进行处理,使它在程序中成为独一无二的词汇. 名称的特殊处理 一般而言,member的名称前面会由编译器加上class名称,形成独一无二的命名

c++ virturn function -- 虚函数

pure irtual function  -- 纯虚函数 先看例子 #include <iostream> using namespace std; class Polygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b; } virtual int area() = 0 ;//{return 0;} // _vptr.Polygon show difre

Function 语意学

概述 在前面文章<C++对象模型>可以知道,class 中成员函数的类型有:nonstatic member function.static member function.virtual member function:不同类型的成员函数的调用会有不同的表现,以下对每一种类型的成员函数进行简单的分析. nonstatic member functions 为了使 nonstatic member function 能够与非成员函数具有相同的效率,C++ 编译器内部将 nonstatic me

(C/C++ )Interview in English - Virtual

Q: What is virtual function?A: A virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature. This concept is an important part of the polymorphism porti

第四章、function语意学

情况一:非静态成员函数C++的设计准则就是非静态成员函数至少和一般的非静态函数有相同的效率,因此非静态成员函数会被改写:举个例子:float Point3d::magnitude3d()const {return x;}①改写函数原型,添加一个额外的参数this到member function中,用于提供一个存取管道,使得class object得以掉用该函数.float Point3d::magnitude3d(const Point3d *const this) {return x;}如果是

C++对象模型——指向Member Function的指针 (Pointer-to-Member Functions)(第四章)

4.4 指向Member Function的指针 (Pointer-to-Member Functions) 取一个nonstatic data member的地址,得到的结果是该member在 class 布局中的byte位置(再加1),它是一个不完整的值,须要被绑定于某个 class object的地址上,才可以被存取. 取一个nonstatic member function的地址,假设该函数是nonvirtual,则得到的结果是它在内存中真正的地址.然而这个值也是不全然的,它也须要被绑定