在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 == b2
在main()
?
答案 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==
了解详情
编辑:
如果你真的想玩游戏,你会注意到我说没有隐式转换是可能的,但有些显式转换是。因为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]