朋友功能的使用声明

时间:2016-11-29 18:07:41

标签: c++ c++11 c++14 using friend

在C ++ 11中,可以通过using声明使外部(公共)可以访问私有基类的公共成员。例如

class A {
private:
    int i = 2;
public:
    void f() { i = 3; }

    friend bool operator==(const A& l, const A& r) { return l.i == r.i; }
};

class B : private A {
public:
    using A::f;
};

int main() {
    B b, b2;
    b.f();
}

b.f()是可能的,因为using A::f定义中的B

是否有可能编写一个类似的声明,该声明可以使朋友函数B&A&升级到operator==(A&, A&),以便可以调用b == b2main()

1 个答案:

答案 0 :(得分:4)

不,只有B可以在内部投放到A,否则就无法实现,因为从客户的角度来看B不是 {{ 1}}而是 A

即使您使用成员函数A替换了friend bool operator=

equals

在编译时,你不能调用class A { private: int i = 2; public: void f() { i = 3; } bool equals(const A& r){return i == r.i;} }; class B : private A { public: using A::f; using A::equals; }; ,因为从调用者的角度来看,从b.equals(b2)类型到B类型不能进行隐式转换(由于私有继承) )。

您需要提供自己的A或将您的继承权更改为operator==public。以下是protected声明自己的B

的示例
friend bool operator==

isocpp

了解详情

编辑: 如果你真的想玩游戏,你会注意到我说没有隐式转换是可能的,但有些显式转换是。因为class B : private A { public: using A::f; friend bool operator==(const B& l, const B& r) { return (static_cast<A>(l) == static_cast<A>(r)) && true; // "true" is a stand-in for some other condition } }; 在技术上从B派生,你可以做指针转换以使其工作,但我不推荐它:

A

或者,如果您希望保留原始的class A { private: int i = 2; public: void f() { i = 3; } bool equals(const A* r){return i == r->i;} }; class B : private A { public: using A::f; using A::equals; }; int main() { B b, b2; b.f(); (::A*)(&b)->equals((::A*)(&b2)); } 语法

,您可以使用指针转换的丑陋表兄,引用转换
operator==

有关更多信息,请参见§11.2[class.access.base]