[英]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::ostream
和Derived
。 接下来,考虑所有可用函数,编译器将检查它们是否可以接受这些类型的参数。 由于Derived
继承了Base
并且向上隐式是隐式的(可以由编译器执行,而无需您明确声明),因此每个采用Base
函数(或const
/ non- const
指针/对Base
引用)也可以采用Derived
和因此是有效的匹配。 对于您的operator<<
这里就是这种情况。
接下来,将所有匹配的重载从最佳匹配到最差(但仍然有效)匹配进行排序。 比赛的质量在此由编程语言规定。 如果存在单个最佳匹配,则选择那个。 如果两个或多个重载同样好,那么重载解决方案将是模棱两可的,编译器无法决定选择哪个重载。 在您的特定情况下,只有一个功能被选中。
您是否需要添加一个附加函数ostream& operator<<(ostream&, const Derived&)
,该ostream& operator<<(ostream&, const Derived&)
将由编译器选择,因为它更适合于std::ostream
和Derived
类型的参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.