提问人:Tomáš Nadrchal 提问时间:8/3/2023 最后编辑:Tomáš Nadrchal 更新时间:8/4/2023 访问量:46
带有枚举类参数的静态成员变量的 friend 函数
friend function to static member variable with enum class parameter
问:
我在命名空间 N 中有 2 个类,类 A 和类 B。
A 类具有 B 类容器。类 B 将结构 S 作为私有静态成员(每个对象 B 的设置)。私有的原因是我想通过类 A 访问这个静态成员。
所以我在类 A 中有成员函数,它设置类 B 的私有静态成员。
在类 B 中使用效果很好,但是我想限制它,只有类 A 的成员函数 setC 是类 B 的朋友。
另一件事是,在类 A 中,我有枚举类 Type,它有助于在结构体 S 中设置相应的变量。friend class A;
如何使用 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
ifndef A_HPP
#define A_HPP
// definition of A
#endif
ifndef B_HPP
#define B_HPP
ifndef A_HPP // now again defined already
#define A_HPP
// definition of A, not active again, but this time
// it doesn't matter as it's already there above
#endif
// definition of B now seeing A
// (not from its own include but the previous one)
#endif
下一个:C++ 中的隐藏好友概念
评论
A::Type
setS
A
setS
setC
#include "B.hpp"
在 A.hpp 中不需要(并删除循环依赖问题)。one
two
int
0
1