基类的虚拟朋友函数?

Kur*_*dey 11 c++ virtual class function friend

我正在学习语言,这是一个否定的怀疑.

是否可以使用虚拟朋友功能?我不知道是否可能,我甚至没有测试它,但它在某些情况下可能有用.例如,对于重载运算符<<().

DerivedClass dc;
BaseClass &rbc = dc;
cout << rbc;
Run Code Online (Sandbox Code Playgroud)

我的猜测是可能的,但我不确定,因为朋友的功能没有在类设计中实现,理论上也不是它的一部分(尽管在这个例子中,从概念上讲,运算符<<()应该是一个意义方法,但由于语法限制,不可能将其实现为一个).

编辑:我关心的是这个例子:

BaseClass bc;
DerivedClass dc;
BaseClass *pArr[2];
pArr[1] = bc;
pArr[2] = dc;
for (int i = 0; i < 2; i++)
    cout << pArr[i];
Run Code Online (Sandbox Code Playgroud)

在这个混合对象数组中,我想要为每个对象调用正确的运算符<<().

Kir*_*rov 35

不,friend virtual功能根本没有意义.

friend函数是这样的,它们不是方法(也就是成员函数),并且有权访问private/ protected成员class.

virtual函数只能是成员函数.你不能拥有virtual非会员功能.


您可以operator<<对基类进行引用,然后调用某个virtual成员函数.这样,你可以做operator<<"几乎虚拟":)


例如

class A
{
public:
    virtual void f() const { std::cout << "base"; }
};
class B: public A
{
public:
    virtual void f() const { std::cout << "derived"; }
};

std::ostream& operator<<(std::ostream& os, const A& a )
{
     a.f();
     return os;
}

int main()
{
    B b;
    std::cout << b << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

将打印derived.


Nee*_*asu 9

虚拟朋友功能成语

C++中的友元函数不能声明为虚拟,因此不能动态绑定友元函数.如果层次结构中的每个类都需要重载的友元函数,则将友元函数应用于整个类的层次会变得很麻烦.缺乏对动态绑定的支持使得很难证明它实际上是类接口的扩展.虚拟朋友功能成语优雅地解决了这个问题.

您需要使用虚拟朋友功能惯用法.它在gist中所说的是在Base中保留一个虚函数,让friend函数调用该函数.这将多态调用派生类的功能

直接从链接复制示例

class Base {
  public:
    friend ostream& operator << (ostream& o, const Base& b);
  protected:
    virtual void print(ostream& o) const{ ... }
};
/* make sure to put this function into the header file */
inline std::ostream& operator<< (std::ostream& o, const Base& b){
  b.print(o); // delegate the work to a polymorphic member function.
  return o;
}

class Derived : public Base {
  protected:
    virtual void print(ostream& o) const{ ... }
};
Run Code Online (Sandbox Code Playgroud)


jua*_*nza 6

您可以在没有朋友功能的情况下使用公共虚拟方法解决此问题:

struct BaseClass {
  virtual void print(std::ostream& os) const;
};

struct DerivedClass {
  virtual void print(std::ostream& os) const;
};

std::ostream& operator<<(std::ostream& os, const BaseClass& obj) {
  obj.print(os);
  return os;
}
Run Code Online (Sandbox Code Playgroud)

如果print方法公开没有意义,那么ostream& operator<<可以声明为friend.