友元函数的使用声明
using-declaration for friend function
在 C++11 中,可以使用 using
声明使私有基 class 的 public 成员可从外部访问(public) .例如
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()
是可能的,因为 B
.
定义中的 using A::f
是否可以编写一个类似的声明,使友元函数 operator==(A&, A&)
可以从 B&
向上转换到 A&
,这样 b == b2
就可以在 main()
被调用?
不,只有 B
可以在内部将自己转换为 A
,否则是不可能的,因为从客户的角度来看 B
不是 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
}
};
在 isocpp
阅读更多内容
编辑:
如果你真的想玩游戏,你会注意到我说 implicit 转换是不可能的,但有些 explicit 转换是可能的。因为 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]了解更多
在 C++11 中,可以使用 using
声明使私有基 class 的 public 成员可从外部访问(public) .例如
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()
是可能的,因为 B
.
using A::f
是否可以编写一个类似的声明,使友元函数 operator==(A&, A&)
可以从 B&
向上转换到 A&
,这样 b == b2
就可以在 main()
被调用?
不,只有 B
可以在内部将自己转换为 A
,否则是不可能的,因为从客户的角度来看 B
不是 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
}
};
在 isocpp
阅读更多内容编辑:
如果你真的想玩游戏,你会注意到我说 implicit 转换是不可能的,但有些 explicit 转换是可能的。因为 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]了解更多