C+中的双边友元函数+;:如何使其编译? 我有以下C++文件:
A.h A.cpp B.cppC+中的双边友元函数+;:如何使其编译? 我有以下C++文件:,c++,friend-function,C++,Friend Function,A.h A.cpp B.cpp #包括“B.h” #包括 #包括“A.h” B::B() { 这->m_b=101; } 空B::B(常数A和A) { std::cout您正在使用未知类型: friend void A::a(const B &b); 编译器只知道类A存在,其他什么都不知道。 您可以将整个类A声明为好友: friend class A; 实际上,在您的例子中,您正在创建一个循环依赖项 通常用前向声明来避免,但据我所知,C++不允许我们对成员函数进行正向声明,所以现在
#包括“B.h”
#包括
#包括“A.h”
B::B()
{
这->m_b=101;
}
空B::B(常数A和A)
{
std::cout您正在使用未知类型:
friend void A::a(const B &b);
编译器只知道类A存在,其他什么都不知道。
您可以将整个类A声明为好友:
friend class A;
实际上,在您的例子中,您正在创建一个循环依赖项
通常用前向声明来避免,但据我所知,C++不允许我们对成员函数进行正向声明,所以现在看来我不可能。< /P>
但当您将
class
声明为friend
时,可以打破循环依赖关系
a、 h
a、 cpp
b、 cpp
#包括“b.h”
#包括“a.h”
#包括
B::B()
{
这->m_b=101;
}
空B::B(常数A和A)
{
std::cout不可能有B的成员函数a的朋友和a的成员函数a的朋友
有几种方法可以克服这个问题
以非成员身份编写一个或两个函数。如果需要,请让他们成为这两个类的朋友
使整个类成为另一个类的朋友。如果权限太广,则提取一个较小的类作为朋友
将两个类都转换为类模板(模板参数无关紧要)
enum单元{u};
甲级模板;
B类模板
{
静态void foo(){}
静态空条(){A::foo();}
friend void A::bar();
};
模板类别A
{
静态void foo(){}
静态无效条(){B::foo();}
friend void B::bar();
};
使用AX=A;
使用BX=B;
你试图设置循环依赖。这是一个可怕的事情,它在很多用例中被禁止。在C++中,规则是,在声明后,即使它被完全定义,也可以使用任何对象。问题是,成员只由类的定义声明。所以,如果一个类(B)需要使用的是它定义另一个类的成员(比如A),那么A必须在B.之前定义,因为在同一时间之前不能定义一个定义的B和B,所以在C++中你将无法实现你想要的。
如果您发现自己试图在B中将a的一个成员设置为friend,在a中将B的一个成员设置为friend,那么您就有了一个一般的设计问题。如果它有意义(从模型的角度来看),可以通过将一个完整的类设置为friend来解决(这是@zmb的答案),或将成员函数更改为非成员。但我强烈建议您返回一步,尝试构建分层模型,而不是循环模型。不幸的是,这成为一个设计问题,而不是编程问题,因此我恐怕无法在以下方面为您提供更多帮助…哪一行是错误行?我认为类dB的定义需要在a之前进行,a类的函数也需要在a之后进行定义。您可能需要在标题“a”的顶部添加:class a;class B;以及移动“a”下面的函数可能是重复的,还没有解决,你真的需要朋友函数吗?你不能只在两个类中都有访问函数吗?你不能在C++中实现这个。是的,我知道。但是我们不想把B类暴露给其他可能存在于A中的函数。这和@ ZMB的回答类似。无论如何,谢谢。似乎是最全面的答案,值得接受
#ifndef B_H
#define B_H
class A;
class B
{
private:
int m_b;
public:
B();
void b(const A &a);
friend void A::a(const B &b); // error: invalid use of incomplete type 'class A'
};
#endif // B_H
#include "B.h"
#include
#include "A.h"
B::B()
{
this->m_b = 101;
}
void B::b(const A &a)
{
std::cout << a.m_a << ".\n";
}
friend void A::a(const B &b);
friend class A;
#ifndef A_H
#define A_H
#include "b.h"
class B;
class A
{
private:
int m_a;
public:
A();
void a(const B &b);
friend class B;
};
#endif // A_H
#include "a.h"
#include "b.h"
#include <iostream>
A::A()
{
m_a = 100;
}
void A::a(const B &b)
{
std::cout << b.m_b << ".\n";
}
#ifndef B_H
#define B_H
class A;
class B
{
private:
int m_b;
public:
B();
void b(const A &a);
friend class A;
};
#endif // B_H
#include "b.h"
#include "a.h"
#include <iostream>
B::B()
{
this->m_b = 101;
}
void B::b(const A &a)
{
std::cout << a.m_a << ".\n";
}
enum unit {u};
template <unit X> class A;
template <unit X> class B
{
static void foo() {}
static void bar() { A<X>::foo(); }
friend void A<X>::bar();
};
template <unit X> class A
{
static void foo() {}
static void bar() { B<X>::foo(); }
friend void B<X>::bar();
};
using AX = A<u>;
using BX = B<u>;