我在 命名空间 N 中有 2 个类,A 类 和 B 类。 A 类 具有B 类 的容器。 类 B 将 struct S 作为私有静态成员(每个对象 B 的设置)。私有的原因是我想通过class A访问这个静态成员。 所以我在 class A 中有成员函数,它设置 class B 的私有静态成员。 在
B中使用
friend class A;
效果很好,但我想限制它,只有 A 类 setC 的成员函数是 B 类 的友元。
另一件事是,在 A 类中,我有 enum class Type,它有助于在 struct S 中设置相应的变量。
如何使用 setS 作为 B 类的友元函数来做到这一点?
注意: 为了便于阅读,我将这两个类放在单独的文件中,我希望拥有它。
简约代码示例:
A.hpp
#ifndef A_HPP
#define A_HPP
#include "B.hpp"
#include <vector>
namespace N
{
class B;
class A
{
public:
enum class Type
{
one,
two,
};
A();
void addValue (int value);
void printContainer ();
void setS (Type type, int number);
void printS ();
private:
std::vector<B> container;
};
} // namespace N
#endif // A_HPP
B.hpp - 内部实现以使其简单
#ifndef B_HPP
#define B_HPP
#include "A.hpp"
#include <iostream>
namespace N
{
class A;
class B
{
public:
B(int val) :
value (val)
{
}
// friend class A; this works as it should
friend void A::setS(A::Type type, int number); // error N::A::Type has not been declared
void print () {std::cout << "Value: " << value << "\n";}
static inline void printS () {std::cout << s.first << " | " << s.second << std::endl;}
private:
struct S
{
int first;
int second;
};
static inline S s;
int value;
};
} // namespace N
#endif // B_HPP
A.cpp - 实施
#include "A.hpp"
#include "B.hpp"
namespace N
{
A::A()
{
// empty ctor
}
void A::setS(Type type, int number)
{
switch (type)
{
case Type::one:
B::s.first = number;
break;
case Type::two:
B::s.second = number;
break;
}
}
void A::printS ()
{
B::printS();
}
void A::addValue (int value)
{
container.push_back(value);
}
void A::printContainer ()
{
for (auto& value : container)
{
value.print();
}
}
} // namespace N
main.cpp 只是完整的示例
#include "A.hpp"
#include <iostream>
int main ()
{
N::A a;
a.setS(N::A::Type::one, 5);
a.printS();
a.addValue(1);
a.addValue(2);
a.addValue(3);
a.printContainer();
std::cout << std::flush;
return 0;
}
您的情况的主要问题是循环包含!
当然,#include "A.hpp"
会引发,将其内容包含到当前文件中,然后包含B.hpp
,最后又包含该内容A.hpp
- 然后生成的代码如下所示:
ifndef A_HPP
#define A_HPP
ifndef B_HPP
#define B_HPP
ifndef A_HPP // but it IS defined already, see above!!!
#define A_HPP
// definition of A,
// but NOT active!
#endif
// definition of B, NOT seeing A, as not active
#endif
// active definition of A
#endif
你需要打破循环包含!
B.hpp
确实依赖于A.hpp
,因为你依赖于嵌套类型(我假设你不想改变......),你不能预先声明它,这不受语言支持(不幸的是)。另一方面,您不需要在 A
内预先声明 B.hpp
– 您已经包含了,不是吗(好吧,到目前为止还没有工作,但我们将修复...)?
不过,只要预先声明 A.hpp
就可以了(只要您仅在 B
内访问 std::vector
成员),因此您可以(并且需要)删除 A.cpp
的包含
。现在包括 B.hpp
和 A.hpp
结果:B.hpp