繁体   English   中英

C ++中的继承和好友功能

[英]Inheritance and Friends Function in C++

我读到,由于friend函数不是成员函数,因此它永远不会被继承。 我尝试了以下代码

#include <iostream>
#include <string>

using namespace std;

class Base {
    char *m_str;
public:
    Base(void): m_str("Base Default") { }
    friend ostream & operator<<(ostream & , const Base &);
};

ostream & operator<<(ostream &os , const Base &b) {
    os << "Base String : " << b.m_str << endl;
    return os;
}

class Derived : public Base {
    char *m_dstr;
public:
    Derived(void): Base(), m_dstr("Derived Default") {  }
};
int main(void) {
    Derived obj3;
    cout << obj3;
    return 0;
}

和o / p是:-基本字符串:基本默认

我的理解是我在编译时应该出错。 但是我认为它起作用是因为编译器内部使用派生对象作为基类引用。 这个理由正确吗?

请注意,我已经直接将字符串文字地址分配给了指针,而不是将字符串复制到动态分配的内存中。

这没什么奇怪的。

实际上, operator<<是一个自由函数,不属于Base一部分, Base仅指定该函数是该类的朋友。

然后,您继续调用此函数并为其提供Derived对象。 Derived对象也是 Base对象,因此为operator<<指定的重载有效。 这与是否继承函数无关,也与friend没有关系。

尝试使用带有Base任何其他免费函数,它同样有效。

您的operator<<是免费功能。 因此,它既没有继承,也没有与其他任何自由函数不同的对待方式(无论是否友好)。

现在,当编译器处理cout << obj3语句时, cout << obj3发生通常的重载解析。 为此,要检查参数的类型,在本例中为std::ostreamDerived 接下来,考虑所有可用函数,编译器将检查它们是否可以接受这些类型的参数。 由于Derived继承了Base并且向上隐式是隐式的(可以由编译器执行,而无需您明确声明),因此每个采用Base函数(或const / non- const指针/对Base引用)也可以采用Derived和因此是有效的匹配。 对于您的operator<<这里就是这种情况。

接下来,将所有匹配的重载从最佳匹配到最差(但仍然有效)匹配进行排序。 比赛的质量在此由编程语言规定。 如果存在单个最佳匹配,则选择那个。 如果两个或多个重载同样好,那么重载解决方案将是模棱两可的,编译器无法决定选择哪个重载。 在您的特定情况下,只有一个功能被选中。

您是否需要添加一个附加函数ostream& operator<<(ostream&, const Derived&) ,该ostream& operator<<(ostream&, const Derived&)将由编译器选择,因为它更适合于std::ostreamDerived类型的参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM