友元函数的使用声明
using-declaration for friend function
在 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
定义中的using A::f
,b.f()
是可能的。
是否可以编写一个类似的声明,使 friend 函数operator==(A&, A&)
从B&
向上转换为A&
,以便可以在main()
中调用b == b2
?
不,只有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阅读更多内容
编辑: 如果你真的想玩游戏,你会注意到我说过隐式转换是不可能的,但一些显式转换是可能的。因为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++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 在c++中在类外声明函数有什么好处
- 使用 #define 声明函数
- 在静态库中声明函数,在使用该相同库的应用程序中定义它
- 如何强制编译器在 C/C++ 本身中声明函数?
- 如果您只需要在 .h 文件中声明函数.cpp是否需要在 .h 文件中声明函数?
- C++:<sys/sysctl.h> 无法声明函数CTL_HW和HW_NCPU
- 尝试声明函数的局部变量,但得到范围错误
- 如何在C++模板中声明函数
- 如何在另一个文件的类中声明函数
- 使用非类型模板参数正向声明函数模板
- 在此范围错误中未声明函数错误
- 当我们不能声明函数内联(GCC 编译器)时?
- 未在此作用域中声明函数,即使存在头文件也是如此
- 无法声明函数中的模板类型别名
- 单个CPP文件中多次声明函数声明可以吗?
- 编译一个支持VBA中声明函数的dll
- 使用从外部参数包中获取的参数类型声明函数
- 使用类成员正确地声明函数
- 在函数内重新声明函数