【问题标题】:Hiding a class from outside when use is only for inside an API in C++仅在 C++ 中的 API 内部使用时从外部隐藏类
【发布时间】:2012-02-06 03:29:02
【问题描述】:

在像 Java 这样的语言中,您可以声明一个不带修饰符的类,这样它就只能在同一个包中可见。我需要在 C++ 中做类似的事情。我正在尝试创建一个 API,它将成为其他应用程序中使用的库。在向程序员 Stackexchange 询问this 问题后,我决定使用某种句柄,它只是一个传递给 API 函数的无符号整数,然后它将传递给一个类,该类将在某些排序表并返回指向句柄表示的对象的指针,返回给函数。然后将允许 API 函数对指针进行操作,但公众永远无法访问指针。

问题是,我希望处理句柄的类对公众不可见(即使公众没有包含句柄的类的实例),因为它只需要在API 函数。另外,我希望这个句柄类成为一个模板(只需要编译 API),因为我很可能有代表不同类型的类的句柄(尽管我可能会使用一个包含 void 指针的表,但它似乎是有点不安全)。我无法在 .cpp 文件中隐藏该类,因为在组成 API 的多个 .cpp 文件中需要它。

另外,我正在考虑在任何具有公共函数的类中使用 pimpl 惯用语,这样,如果其中有任何私有函数需要与我的一个对公众隐藏的类相关的参数,头文件包括API 用户无需将隐藏类包含在 API 库中即可编译程序。

那么,将仅在其他类(分布在多个 .h 和 .cpp 文件中)中需要的类隐藏在 API 自身内部的最佳方法是什么?

【问题讨论】:

    标签: c++


    【解决方案1】:

    您确实可以使用 PIMPL 成语;只需编写类型的前向声明并使用指向它的(智能)指针作为成员。那应该处理头文件。

    对于实现,只需有一个单独的头文件,该头文件包含在库的实现中,但不包含在接口的任何部分中。示例:

    // Interface.h
    
    class Secret;
    
    class Hi {
    public:
        Hi();
        ~Hi();
    
        void stuff();
    
    private:
        Secret* secret;
    };
    

    // Implementation.cpp
    
    #include "Secret.h"
    #include "Interface.h"
    
    Hi::Hi() : secret(new Secret) { }
    Hi::~Hi() { delete secret; }
    
    void Hi::stuff() { secret->stuff(); }
    

    // Secret.h
    
    class Secret {
    public:
        int data;
        void stuff() { ... }
    };
    

    【讨论】:

      【解决方案2】:

      您不必专门隐藏它,只是不要在定义您的 API 的 .h 文件中包含内部标头。

      对于一个项目来说,具有不属于外部接口的内部帮助类和函数是完全正常的。将它们编译到您的库中,但不要分发标头。

      【讨论】:

        【解决方案3】:

        这可能不是最好的解决方案,特别是如果您需要在没有共同祖先的多个类中使用该类,但您可以使用私有或受保护的嵌套类:

        class Foo {
        protected:
            class SecretClass {
                // ...
            };
            // ...
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-25
          相关资源
          最近更新 更多