我正试图强制来自特定类的函数调用者。 例如,此代码显示我的问题。 我想让“使用”功能只能从A类调用。 我在整个项目中使用全局命名空间。
A.H
#include "b.h"
namespace GLOBAL{
class A{
public:
void doSomething(B);
}
}
a.cpp
#include "a.h"
using namespace GLOBAL;
void A::doSomething(B b){
b.use();
}
b.h
namespace GLOBAL{
class B{
public:
friend void GLOBAL::A::doSomething(B);
private:
void use();
}
编译说:
‘GLOBAL::A’ has not been declared
‘void GLOBAL::B::use()’ is private
有人可以帮忙吗?
非常感谢,
麦克
答案 0 :(得分:2)
这是因为在朋友退场时你正在引用一个班级的成员。
为此,编译器必须已经看到了A的完整定义。
// #include "b.h" // remove this line it is not needed.
namespace GLOBAL{
class B; // Forward declare the class here.
class A{
public:
void doSomething(B&); // Note: This should probably be a reference.
// Change to doSomething(B&);
}
}
// Add this line it is needed for the friend declaration.
// To have a member as a friend we need the definition of 'A'
#include "a.h"
namespace GLOBAL{
class B{
public:
friend void GLOBAL::A::doSomething(B&);
private:
void use();
}
#include "a.h"
// Add this line to include the B definition so you know how to call use()
#include "b.h"
using namespace GLOBAL;
void A::doSomething(B& b){ // b should be a reference otherwise you are copying it.
b.use();
}
答案 1 :(得分:1)
以下编译从cpp文件中编译好:
namespace GLOBAL
{
class B;
class A
{
public:
void doSomething(B& b);
};
};
namespace GLOBAL
{
class B
{
public:
friend void GLOBAL::A::doSomething(B&);
private:
void use()
{
}
};
};
void GLOBAL::A::doSomething(B& b)
{
b.use();
}
最好的我可以告诉你的问题是因为你在定义A类之前定义B类的“a.h”中加入了“b.h”而B类引用了A类。所以你有问题。但是,您无法转发声明类型B的对象,因为您正在通过堆栈进行复制。因此,为什么我使用对B类的引用(因为这不需要事先知道B对象)。
基本上你的结构存在一些基本问题需要解决。您需要在forward declarations和circular dependencies
上进行一些阅读编辑:纯粹指定A类是B的朋友(而不是A中引用B的特定函数)实际上是可能的,因为朋友定义提供了一种前向声明。因此,以下代码编译:
namespace GLOBAL
{
class B
{
public:
friend class A;
private:
void use()
{
}
};
};
namespace GLOBAL
{
class A
{
public:
void doSomething(B b);
};
};
void GLOBAL::A::doSomething(B b)
{
b.use();
}
在您的代码中,最初发布,将好友声明添加到,只需
friend class A;
应该允许你的代码编译。
答案 2 :(得分:0)
在第一个#include "b.h"
指令后,将a.h
从a.cpp
移至#include
。编译器在编译声明适用的函数之前不需要查看友元声明。