C++ 朋友成员函数行为看起来不稳定
C++ friend member function behaviour looks erratic
我一直试图避免朋友的概念,因为它违背了封装的目的。然而,我只是在试验这个概念,下面的代码无法编译并出现以下错误:
main.cpp:29:28: error: ‘int A::a’ is private within this context
另一方面,如果我只是将 class B 放在 class A 之前,并向前声明 class A,它运行良好。我在这里错过了一些非常微不足道的东西吗?
#include <iostream>
class A {
int a;
public:
A() { a = 0; }
// friend function
friend void B::showA(A& x);
};
class B
{
public:
void showA(A&);
private:
int b;
};
void B::showA(A& x)
{
// Since showA() is a friend, it can access
// private members of A
std::cout << "A::a=" << x.a;
}
int main()
{
A a;
B b;
b.showA(a);
return 0;
}
实际上,您在 class A 中使用了 class B,但是如您所见,B 在使用之前并未声明。
这导致了这样的错误:
error: 'B' has not been declared
还有一点
error: int 'A::a' is private within this context
因为第一个错误导致好友关系没有链接(因为A::a默认是私密的)
你可以试试forward-declare B
,像下面这样
#include<..>
class B;
class A {
int a;
public:
A() { a = 0; }
// friend function
friend void B::showA(A& x);
};
class B{
...
}
...
这会产生一个错误 error: invalid use of incomplete type 'class B'
因为前向声明只说明特定的
class(此处class B
)将在稍后定义,因此您可以引用它或指向它,但它没有说明这个class是什么成员
会有,因此编译器无法知道您的 future class B
是否会有 B::showA
方法,因此会出现错误 incomplete type error
。这时候编译器不知道你以后的classB(用在classA中)会不会有函数B::showA
.
最简单的解决方案是在 A
之前声明 B
,然后向前声明 A
(使用 class A;
),如下所示。这样,你告诉编译器——这是我的 class B
声明(它包含一个方法 B::showA
),
它使用我稍后定义的 class A
。由于不需要知道 A
的内容是什么,它会编译。
// as you use class A before it is declared, you need to forward declare it
class A;
class B
{
public:
void showA(A&);
private:
int b;
};
class A {
int a;
...
这将编译并执行函数 B::showA
。
我一直试图避免朋友的概念,因为它违背了封装的目的。然而,我只是在试验这个概念,下面的代码无法编译并出现以下错误:
main.cpp:29:28: error: ‘int A::a’ is private within this context
另一方面,如果我只是将 class B 放在 class A 之前,并向前声明 class A,它运行良好。我在这里错过了一些非常微不足道的东西吗?
#include <iostream>
class A {
int a;
public:
A() { a = 0; }
// friend function
friend void B::showA(A& x);
};
class B
{
public:
void showA(A&);
private:
int b;
};
void B::showA(A& x)
{
// Since showA() is a friend, it can access
// private members of A
std::cout << "A::a=" << x.a;
}
int main()
{
A a;
B b;
b.showA(a);
return 0;
}
实际上,您在 class A 中使用了 class B,但是如您所见,B 在使用之前并未声明。 这导致了这样的错误:
error: 'B' has not been declared
还有一点
error: int 'A::a' is private within this context
因为第一个错误导致好友关系没有链接(因为A::a默认是私密的)
你可以试试forward-declare B
,像下面这样
#include<..>
class B;
class A {
int a;
public:
A() { a = 0; }
// friend function
friend void B::showA(A& x);
};
class B{
...
}
...
这会产生一个错误 error: invalid use of incomplete type 'class B'
因为前向声明只说明特定的
class(此处class B
)将在稍后定义,因此您可以引用它或指向它,但它没有说明这个class是什么成员
会有,因此编译器无法知道您的 future class B
是否会有 B::showA
方法,因此会出现错误 incomplete type error
。这时候编译器不知道你以后的classB(用在classA中)会不会有函数B::showA
.
最简单的解决方案是在 A
之前声明 B
,然后向前声明 A
(使用 class A;
),如下所示。这样,你告诉编译器——这是我的 class B
声明(它包含一个方法 B::showA
),
它使用我稍后定义的 class A
。由于不需要知道 A
的内容是什么,它会编译。
// as you use class A before it is declared, you need to forward declare it
class A;
class B
{
public:
void showA(A&);
private:
int b;
};
class A {
int a;
...
这将编译并执行函数 B::showA
。