C++ 将类成员函数指定为另一个类的友元?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10546391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Specify a class member function as a friend of another class?
提问by ipkiss
According to the C++ Primer book, the author mentioned that We can specify a class member function as a friend of another class, instead of the entire class (page 634).
根据 C++ Primer 一书,作者提到我们可以将类成员函数指定为另一个类的友元,而不是整个类(第 634 页)。
Then, I tested this code:
然后,我测试了这段代码:
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
I just wanted the fB() to be friend of class A, not the entire class B. But the about code produced an error: 'B' : is not a class or namespace name
.
(I am using Visual C++ 2005)
我只是想FB()是A级的朋友,而不是整个类B.但有关代码产生的错误:'B' : is not a class or namespace name
。(我使用的是 Visual C++ 2005)
回答by juanchopanza
Try putting the B definition before A's:
尝试将 B 定义放在 A 之前:
class A; // forward declaration of A needed by B
class B
{
public:
// if these require full definition of A, then put body in implementation file
void fB(A& a); // Note: no body, unlike original.
void fB2(A& a); // no body.
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
A
needs the full definition of B
. However, B
needs to know about A
, but does not need the full definition, so you need the forward declaration of A
.
A
需要完整的定义B
。但是,B
需要知道 about A
,但不需要完整定义,因此需要A
.
回答by SrinivasPaladugu
When the compiler starts compiling the code( usually from top ) and it encounters this line:
当编译器开始编译代码(通常从 top 开始)并遇到以下行时:
friend void B::fB(A& a);
- at this point, compiler has no idea about type info of B so it throws an error ( 'B' : is not a class or namespace name ).
by forward declaration of class B, compiler knows about type of B is Class in advance to its actual declaration with all members.
run below code after forward declaration of class B.
- 此时,编译器不知道 B 的类型信息,因此它会引发错误( 'B' : is not a class or namespace name )。
通过类 B 的前向声明,编译器在其所有成员的实际声明之前就知道 B 的类型是 Class。
在 B 类前向声明后运行下面的代码。
///////////////
///////////////
class B;
class A
{
public:
friend void B::fB(A& a);
void fA(){};
};
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
Still error !!!
还是报错!!!
because forward declaration is just a declaration of an identifier for which the programmer has not yet given a complete definition. so compiler needs full definition of B before class A.
因为前向声明只是一个标识符的声明,程序员还没有给出完整的定义。所以编译器需要在类 A 之前完整定义 B。
Note: class A definition dependents on type of B and also definition of B (i.e B::fB) so that forward declaration alone can not resolve, complete definition of class B needs to define before class A.
注意:A 类定义依赖于 B 的类型以及 B 的定义(即 B::fB),因此仅靠前向声明无法解析,B 类的完整定义需要在 A 类之前定义。
4 run this code
4 运行这段代码
////////
////////
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
Still error !!!
还是报错!!!
because class B member functions fB & fB2 having arguments of type A but compiler has no idea about type info of A so by forward declaration of class A, we can let compiler knows about type info of A. Note: class B definition only dependent on type of A not the members of A so that forward declaration of A resolve step 4.
因为 B 类成员函数 fB & fB2 具有类型 A 的参数,但编译器不知道 A 的类型信息,所以通过类 A 的前向声明,我们可以让编译器知道 A 的类型信息。 注意:B 类定义仅依赖于A 的类型不是 A 的成员,以便 A 的前向声明解决步骤 4。
- final code
- 最终代码
////////////////////////
////////////////////////
class A; // forward declaration of A needed by B
class B
{
public:
void fB(A& a);
};
class A
{
int i;
public:
friend void fA(A& a); //specifying function fA as a friend of A, fA is not member function of A
friend void B::fB(A& a); //specifying B class member function fB as a friend of A
};
// fA is Friend function of A
void fA(A& a)
{
a.i = 11; // accessing and modifying Class A private member i
cout<<a.i<<endl;
}
// B::fB should be defined after class A definition only because this member function can access Class A members
void B::fB(A& a)
{
a.i = 22; // accessing and modifying Class A private member i in Class B member function fB
cout<<a.i<<endl;
}
int main()
{
A a;
fA(a); // calling friend function of class A
B b;
b.fB(a); // calling B class member function fB, B:fB is friend of class A
return 0;
}
6 Exercise:
6 练习:
// Cyclic dependency
#include<iostream>
using namespace std;
class A;
class B
{
public:
void fB(A& a);
friend void A::fA(B& b); //specifying class A's member function fA as a friend of B
};
class A
{
int i;
public:
void fA(B& b);
friend void B::fB(A& a); //specifying class B's member function fB as a friend of A
};
int main()
{
return 0;
}
回答by Luchian Grigore
For this to work, the full definition of B
needs to be known before the definition of A
.
为此,B
需要在定义之前了解 的完整定义A
。
So forward declare A
, since B
doesn't need the full type, and switch the definitions around:
所以 forward declare A
,因为B
不需要完整类型,并切换定义:
class A;
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
回答by AbhimanyuAryan
When the compiler starts reading the code( usually from top ) and it encounters this line:
当编译器开始读取代码(通常从 top )并遇到以下行时:
friend void B::fB(A& a);
friend void B::fB(A& a);
Then compiler doesn't understand what do you mean by this B::
. Even if you have defined this class later in the code but compiler doesn't know that. So it's usually a good to practice to do forward declaration of class( class Name;
) if the definition resides later in the code.
然后编译器不明白你的意思是什么B::
。即使您稍后在代码中定义了这个类,但编译器不知道。因此,class Name;
如果定义位于代码的后面,那么练习对 class( )进行前向声明通常是一个很好的做法。
回答by abdul rizwan
firstly forward declare class A, so that its visible in class B definition. then define class A containing a friend function from class B.
首先转发声明A类,使其在B类定义中可见。然后定义包含来自类 B 的友元函数的类 A。
回答by New_Bee
First of all before using a particular class name you will have to declare it first. So you will need a forward declaration of the Class B as you are using it in Class A before the Class B has been originally declared.
首先,在使用特定的类名之前,您必须先声明它。因此,在最初声明 B 类之前,在 A 类中使用它时,您将需要 B 类的前向声明。
Secondly you will need to define the functions (that are using variables from both the classes- here the friend functions ) after both the classes have been defined. Or else we may face errors.
其次,在定义了两个类之后,您需要定义函数(使用来自两个类的变量——这里是友元函数)。否则我们可能会遇到错误。
For example
例如
#include<iostream>
using namespace std;
class alpha1;
class alpha2
{
public:
void put_bata(int a,int b);
};
void alpha2 :: put_bata(int a,int b)
{
alpha1 net;
net.roll=a;
net.id=b;
net.get_data();
}
class alpha1
{
int roll;
int id;
public:
void get_data(void)
{
cout<<roll<<endl<<id<<endl;
}
friend void alpha2 :: put_bata(int a,int b);
};
int main()
{
alpha2 gamma;
gamma.put_bata(5,6);
return 0;
}
Will show us errors as put_bata tries to access roll and id before they are defined even if we had a forward declaration of the class but the code given below will just work fine.
将向我们显示错误,因为 put_bata 尝试在定义之前访问 roll 和 id,即使我们有类的前向声明,但下面给出的代码将正常工作。
#include<iostream>
using namespace std;
class alpha1;
class alpha2
{
public:
void put_bata(int a,int b);
};
class alpha1
{
int roll;
int id;
public:
void get_data(void)
{
cout<<roll<<endl<<id<<endl;
}
friend void alpha2 :: put_bata(int a,int b);
};
void alpha2 :: put_bata(int a,int b)
{
alpha1 net;
net.roll=a;
net.id=b;
net.get_data();
}
int main()
{
alpha2 gamma;
gamma.put_bata(5,6);
return 0;
}
回答by mrboieng
@juanchopanza @ipkiss Regarding the problem that you can't access data members of A inside fB(A& a) because A is not defined yet. Instead of defining it in a separate file and including it, you can just define the function fB(A& a) after the definition of class A so that fB(A& a) is able to see data members of A.
@juanchopanza @ipkiss 关于由于 A 尚未定义而无法访问 fB(A& a) 内的 A 数据成员的问题。无需在单独的文件中定义并包含它,您只需在类 A 的定义之后定义函数 fB(A& a),以便 fB(A& a) 能够看到 A 的数据成员。