如何在 public 头文件中向我的库的用户公开一个枚举,但也在内部使用它?

How do I expose an enum to users of my library in a public header file but also use it internally?

如果我正在创建一个公开一个 public 头文件的库,它可能需要或 return 一个 publicly 公开的 enum,我将如何使用它enum 在内部没有在头文件中创建循环依赖?

例如:

Public.h

#include "Internal.h"


namespace PublicFunctions {
    enum Access{
        READ,
        WRITE,
    }

    FileObject CreateFileObject(Access a) {
        return InternalFunctions::GetFileObject(a);
    }
}

Internal.h

#include "Public.h"


namespace InternalFunctions {

    FileObject GetFileObject(PublicFunctions::Access a);
}

Internal.cpp

FileObject InternalFunctions::GetFileObject(PublicFunctions::Access a) {
    if (a == PublicFunctions::Read) {
          return openreadonly();
    }
    else {
              return openwrite();
    }
}

我知道 #praga once 预处理器指令,但是有什么方法可以在这些内部文件中转发声明 enum 吗?

或者 #pragma 曾经是解决这些依赖关系的最佳方法吗?

include guard 无法帮助您,因为如果首先包含 public.h,对于图书馆的客户来说是合乎逻辑的情况,您最终会得到

// public.h already included so #include "Public.h" is ignored 
namespace InternalFunctions {

    FileObject GetFileObject(PublicFunctions::Access a);
    // PublicFunctions::Access not defined yet.
}

namespace PublicFunctions {
    enum Access{
        READ,
        WRITE,
    }

    FileObject CreateFileObject(Access a) {
        return InternalFunctions::GetFileObject(a);
    }
}

更糟糕的是,任何包含 public.h 的人都会看到 internals.h,这破坏了将两者分开的意义。

但是如果您从 public.h 中删除 CreateFileObject 的实现,您可以

namespace PublicFunctions {
    enum Access{
        READ,
        WRITE,
    }

    FileObject CreateFileObject(Access a);
}

并且让 internal.h 一个人呆着。它将被编译库独占使用,不随 public 接口一起提供。

#include "Public.h"

namespace InternalFunctions {

    FileObject GetFileObject(PublicFunctions::Access a);
}

然后是Internal.cpp

#include "internal.h"
FileObject InternalFunctions::GetFileObject(PublicFunctions::Access a) {
    if (a == PublicFunctions::Read) {
          return openreadonly();
    }
    else {
              return openwrite();
    }
}

最后 public.cpp

#include "internal.h"
FileObject PublicFunctions::CreateFileObject(Access a) {
        return InternalFunctions::GetFileObject(a);
    }

是否值得将public.cpp和internal.cpp分开取决于程序员和他们的编码标准。