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

问题描述 投票:0回答:1

我在 命名空间 N 中有 2 个类,A 类B 类A 类 具有B 类 的容器。 类 Bstruct 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;
}
c++ enums static friend
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.