C++ 基类的虚拟朋友函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12142893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:55:57  来源:igfitidea点击:

Virtual friend functions for a base class?

c++classfunctionvirtualfriend

提问by Kurospidey

I'm in the proccess of learning the language and this is a noob doubt.

我正在学习语言的过程中,这是一个菜鸟的疑问。

Is it possible to use a virtual friend function? I don't know if it's possible, I didn't even test it but it could be useful in some situations. For example, for the overloaded operator<<().

是否可以使用虚拟朋友功能?我不知道这是否可能,我什至没有测试过它,但它在某些情况下可能很有用。例如,对于重载的 operator<<()。

DerivedClass dc;
BaseClass &rbc = dc;
cout << rbc;

My guess is it's possible, but I'm not sure since a friend function is not implemented in the class design, and theoretically is not part of it (though in this example, conceptually it makes sense that operator<<() should be a method, but due to syntax limitations it's not possible to implement it as one).

我的猜测是可能的,但我不确定,因为在类设计中没有实现友元函数,理论上它不是它的一部分(尽管在这个例子中,从概念上讲,operator<<() 应该是一个方法,但由于语法限制,不可能将其实现为一个)。

EDIT: my concern is related with this example:

编辑:我的担忧与这个例子有关:

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

in this array of mixed objects, I want the correct operator<<() called for each one.

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

回答by Kiril Kirov

Nope, friendvirtualfunctions doesn't make sense at all.

不,friendvirtual函数根本没有意义。

friendfunctions are such, that are not methods (a.k.a. member functions) and have the right to access private/protectedmembers of a class.

friend功能是这样的,不属于方法(又名成员函数),并具有访问权private/protected的成员class

virtualfunctions can only be member functions. You can't have virtualnon-member function.

virtual函数只能是成员函数。你不能有virtual非成员函数。



You can make the operator<<take a reference to a base class and then call some virtualmember function. This way, you can make the operator<<"almost virtual" :)

operator<<可以引用基类,然后调用一些virtual成员函数。这样,您可以使operator<<“几乎虚拟”:)



For example

例如

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;
}

will print derived.

将打印derived

回答by Neel Basu

Virtual Friend Function Idiom

虚拟朋友功能习语

friend functions in C++ can not be declared virtual and therefore no dynamic binding of friend functions is possible. Applying a friend function to an entire hierarchy of classes becomes awkward if an overloaded friend function is needed for every class in the hierarchy. This lack of support for dynamic binding makes it hard to justify that are in fact an extension of the class's interface. Virtual friend function idiom addresses this concern elegantly.

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

You need to use virtual Friend function idiom. What it says in gist is keep a virtual function in Base and let the friend function call that function. which will polymorphically call that function of Derived Class

您需要使用虚拟 Friend 功能习语。它的要点是在 Base 中保留一个虚函数,并让友元函数调用该函数。它将多态地调用派生类的该函数

Copying the example directly from the link

直接从链接复制示例

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{ ... }
};

回答by juanchopanza

You can solve this without friend functions, using public virtual methods only:

你可以在没有友元函数的情况下解决这个问题,只使用公共虚方法:

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;
}

If it doesn't make sense for the printmethod to be public, then the ostream& operator<<can be declared as friend.

如果将print方法设为 public没有意义,则ostream& operator<<可以将 声明为friend

回答by Bo Persson

You can't be both a friend and a virtual function of the same class. However, a friend operator couldcall a virtual function from the object it is printing.

你不能既是朋友又是同一个类的虚函数。但是,友元运算符可以从它正在打印的对象调用虚函数。

ostream& operator<<(ostream& stream, const BaseClass& rbc)
{
    rbc.print_on(stream);
    return stream;
}

回答by Coding Mash

Virtual Functions are something else than friend functions. Virtual Functions are used only with use of inheritance in the program with one class as base class and other as derived classes. Virtual functions are used for dynamic binding of objects. It means that you can store an object of derived class in a pointer of base class and still call the method of that partiular derived class. The concept is known as Polymorphism.

虚函数不同于友元函数。虚函数仅在程序中使用继承使用,其中一个类作为基类,另一个作为派生类。虚函数用于对象的动态绑定。这意味着您可以将派生类的对象存储在基类的指针中,并且仍然可以调用该特定派生类的方法。这个概念被称为多态性

Friend functions are used to access the private interface of a class. They could be used even when no inheritance has been used in your class.

友元函数用于访问类的私有接口。即使您的类中没有使用继承,它们也可以使用。