声明朋友功能
在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();
}
bf()
是可能的,因为在B
的定义中using A::f
。
是否有可能写一个类似的声明,这将使B&
A&
可能为朋友函数operator==(A&, A&)
进行上调,以便可以在main()
调用b == b2
?
没有,只有B
可以在内部投自己A
,它要不就是不可能的,因为从客户的角度来看, B
不是 A
,而是有 A
即使你用一个成员函数equals
替换了你的friend bool operator=
:
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
}
};
在isocpp阅读更多内容
编辑:如果你真的想玩游戏,你会注意到我说过没有任何隐式转换是可能的,但一些明确的转换是。 因为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==
语法
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();
((::A&)(b)) == ((::A&)(b2));
}
有关更多信息,请参见§11.2[class.access.base]
链接地址: http://www.djcxy.com/p/94199.html