抽象类中的受保护流操作符

时间:2013-07-28 14:19:53

标签: c++ operator-overloading abstract-class protected

我看过一些抽象类的例子,其中有一个朋友operator<<和一个虚拟的“print”成员函数,其中两个声明都在protected部分。例如:

class Function{
public:
    virtual ~Function() {} 
    virtual double value(const double x) const = 0;
    virtual Function* clone() const = 0;
protected:
    friend ostream& operator<<(ostream& os, Function& f);
    virtual void print(ostream& os) const = 0;
};

ostream& operator<<(ostream& os, Function& f){
    f.print(os);
    return os;
}

我不明白为什么这是强制性的。谁能解释一下?

谢谢!

2 个答案:

答案 0 :(得分:1)

首先,声明friend函数/运算符的位置并不重要。它不是publicprotectedprivate。它只是一个friend函数/运算符,因此它可以访问类&#39;成员,无论他们的访问限制。因此,流运营商不受保护。它是friend,这允许它访问print()方法。

其次,print方法应该是private。如果你想从一个更加派生的类中调用基类的protected方法,它只有print才有意义。但是设计表明它是一个实现细节,以便实现ostream& operator<<

另一方面,如果您设计的课程使print方法公开有意义,那么ostream& operator<<就不需要friend }。

答案 1 :(得分:0)

这当然不是强制性的。事实上,我认为它是 糟糕的设计。

你把朋友声明放在哪里并不重要;访问 加速器不适用于它。由于operator<< 部分 公共接口,无论你在哪里声明它,它 在课堂的公共区域宣布它更有意义, 因为那是那些不是从类中派生的用户 寻找它。

关于print功能,我也不是真的 除了公开之外宣布它的原因。鉴于最多, 如果不是所有访问都将通过朋友operator<<, 它可能没关系,但我看不出有什么收获 声明它private。作为一般规则,没有是 通过声明任何内容获得protected;这是非常罕见的使用 protected。在20世纪90年代中期,有人认为你应该这样做 声明virtaul函数protected,而不是public,和 标准库的一部分仍然反映了这个惯例。 但我认为今天的共识是1)如果这个规则 适用,虚函数应为private,而不是 protected,2)此规则并不总是适用于 const函数的情况,如print,它实际上从来没有 适用。