【问题标题】:Is a non-member friend function overloaded operator inherited?非成员友元函数重载运算符是否被继承?
【发布时间】:2021-05-10 04:52:36
【问题描述】:

我有我的父类B,我重载了<< 运算符。看来我的派生类 D 可以使用该运算符,即使我到处都读到类不会从其父类继承 friend 函数。顺便说一句,我使用了公共继承。

我很困惑。这是否有效,因为它是一个重载的运算符,或者任何朋友函数都被孩子继承。另外,如果它们是继承的,我可以以任何方式重新定义它们吗?

【问题讨论】:

    标签: c++ inheritance operator-overloading friend


    【解决方案1】:

    如果您为 B 重载了朋友 operator<<,您可以为 D 调用该运算符,即使它不是 D 的朋友:

    class B {
    public: 
        B(int i=0):v(i){}
    private:
        int v;
    friend ostream& operator<< (ostream& os, const B& b);
    };
    
    class D:public B {
    public:
        D(string s=""s,int i=1) : B(i),v2(s){}
    private:
        string v2;
    };
    
    // access to the private members of B.  B is accessed via a reference. 
    ostream& operator<< (ostream& os, const B& b){
        return os<<b.v; 
    }
    
    int main() {
        B b;
        D d; 
        cout << b <<endl;  // calls operator<< for B
        cout << d <<endl;  // calls operator<< for the B sub-object of D
    }  
    

    Online demo

    对于D 对象,使用DB 主题,因为我上面的代码通过引用传递参数。如果重载将通过值而不是通过引用传递参数,它也可以工作,但 d 对象将被切片为 B 对象。

    在这两种情况下,都会调用父类的运算符重载。

    您也可以为子类重载运算符。但是由于友谊不是继承的,如果您需要访问私人成员,则需要定义一个新的友谊:

    ostream& operator<< (ostream& os, const D& d){
        //return os<<d.v<<d.v2; // not alloewed because D has no visibility on B's private members
        return os << *static_cast<const B*>(&d) << d.v2; 
    }
    

    Demo

    D 的友谊仅限于 D 的私人成员,并且不能访问 B 的私人成员。通常的方法是调用 B 的重载(这里通过转换技巧),并访问 D 的私有成员。

    当然,如果 operator&lt;&lt; 只访问公共成员,我们就不需要任何 freindshop 来处理重载。

    【讨论】:

      猜你喜欢
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 2011-12-05
      • 2013-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多