c++ 友元函数到带枚举类参数的静态成员变量

nle07wnf  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(88)

我在 namespace N 中有两个类,class Aclass Bclass A 具有 class B 的容器。class B 具有 struct S 作为私有静态成员(每个对象的设置 B)。私有的原因是我想通过 class A 访问这个静态成员。所以我在 class A 中有一个成员函数,它设置了 class B 的私有静态成员。在 class B 中使用friend class A;可以正常工作,但是我想限制它,只有类A setC 的成员函数是 class 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;
}

lnvxswe2

lnvxswe21#

您的案例中的主要问题是循环包含!
当然,#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,因为你依赖于一个嵌套类型(我假设你不想改变...),你不能预先声明,这是不支持的语言(不幸的是)。另一方面,你不需要在B.hpp中预先声明A--你已经有了include,不是吗(好吧,到目前为止还没有工作,但是我们要修复...)?
但是,A.hpp可以只预先声明B(只要您仅访问A.cpp中的std::vector成员),因此您可以(并且需要)删除B.hpp的包含。现在,同时包含A.hppB.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

相关问题