c++友元类的问题

class B{
int m;
friend class A;
public:
B():m(2){}
};
class A{
public:
int putb(B b){
return b.m+1;
}
};
这个是可以的,但是将A类放在B类的前面,A类前面再加个class B;就不行了,那怎么做两个类互为友元类?

你这个问题的关键在于,如果把class A定义在前面,其成员函数putb有一句b.m+1,编译器那个时候还不知道b.m是什么,因为之前你只是声明了class B。对于A来说,B还是一个非完整类型,就是只有声明还没有定义那种类型(也许在后面会有详细定义,但是编译器并不知道后面还有啥)。

如果互为友元函数,比较好的解决方法是把实现部分单独写成cpp文件,比如
(注意,楼上那位说的不对,构造函数的实现不影响的,你愿意的话可以写在class原型里)
ab.h文件:
class B
{
int m;
friend class A;
public:
int puta(A a);
B() : m(2)//构造函数可以在这里写,也可以写在实现,对你的问题没有影响
{
}
};
class A
{
int m;
friend class B;
public:
int putb(B b);
A() : m(3)
{
}
};

ab.cpp文件:
#include "ab.h"
int A::putb(B b)
{
return b.m + 1;
}
int B::puta(A a)
{
return a.m + 1;
}

当然,也可以都写到一个.h文件里,但是会有其他问题(超出这个问题的范围,而且一般你不会碰到,可以留言讨论,这里不多说),上代码:
ab.h
class B
{
int m;
friend class A;
public:
int puta(A a);
B() : m(2)
{
}
};
class A
{
int m;
friend class B;
public:
int putb(B b);
A() : m(3)
{
}
};
int A::putb(B b)
{
return b.m + 1;
}
int B::puta(A a)
{
return a.m + 1;
}

也许你看明白了,凡是要用到不完整类型详细细节的代码需要单独实现。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-01-18
需要交叉书写,将类里面的成员函数只写原型,包括构造函数的列表也不要,然后在两个类的后面交错实现各个函数,原则是该函数用到了另外一个类的成员函数或者数据,此时一定该函数体可见,当然,如果没用到则还可以在类里实现
还有,如果有友元的对象成员,必须在后面,前面加上类的前向说明
第2个回答  2011-01-18
class B;
class A{
int m;
friend class B;
public:
B():m(2){}
};
class B{
public:
int putb(B b){
return b.m+1;
}
};
不行是因为没声明,只要在引用前声明就行了,后面在进行定义。
第3个回答  2011-01-19
class B里面 应该声明为public
B();这个不需要写,需要的话应该这样 B(){}
还有B bb(); 是不需要括号的

正确结果

#include<iostream>
using namespace std;

class A
{
friend class B;
public:
A(int aa ):a(aa)
{
cout<<"A"<<endl;
}
private:
int a;
};

class B
{
public:
B(){}
void printa(A & c)
{
cout<<c.a<<endl;
}
};

int main()
{
A aaa(4);
B bb;
bb.printa(aaa);
return 0;
}
相似回答