【问题标题】:How can I hide a class in C++?如何在 C++ 中隐藏一个类?
【发布时间】:2012-12-15 02:06:43
【问题描述】:

假设我有 2 个我希望可见的类(在给定的头文件中)和一个作为其祖先的类,我希望仅对前面提到的两个类可见。如何实现这种在 C++ 中不可见的类功能?

【问题讨论】:

  • 为什么?只需将其抽象化,这样它就不能被实例化,而是用作接口。这有用
  • 你可以命名它们,但我很确定你不能让它们完全无法访问
  • 与其将类设为祖先,不如将其设为包含类,并使用私有实现drdobbs.com/cpp/making-pimpl-easy/205918714
  • 如果他问怎么做,这也是我们的事:)
  • @obmarg:我也是这么说的。被命名空间不会真正 使类不可访问甚至都没有关系。如果您有类似namespace implementationnamespace detail 的课程,并且有些混蛋觉得无论如何都不得不使用它,只是因为它在技术上是可行的,那是他自己的问题。你已经明确了意图,这才是最重要的。如果在他们滥用您明确说明的意图后它崩溃并燃烧,并且他们来抱怨,请告诉他们...关闭。

标签: c++ oop visibility


【解决方案1】:

匿名答案的变体,您可以添加隐藏类的私有成员,而不是私有继承。

class Hidden
{
   private:
      friend class Exposed;
      Hidden() {}
      int hidden_x;
};

class Exposed
{
  public:
      Exposed() {}
      void DoStuff() { printf( "%d" , hidden.hidden_x ); }
  private:
      Hidden hidden_;
};

【讨论】:

    【解决方案2】:

    我建议不要隐藏类,而是使用它。例如:

    class Hidden
    {
      private:
        friend class Exposed;
        Hidden() {}
        int hidden_x;
    };
    
    class Exposed : private Hidden
    {
      public:
        Exposed() : Hidden() {}
        void DoStuff() { printf( "%d" , hidden_x ); }
    };
    

    所以你可以: - 在您的代码中创建任意数量的 Exposed 类实例 - 从这些实例调用 DoStuff() 方法

    但你不能: - 实例化隐藏类(私有构造函数) - 直接或通过 Exposed 类对 Hidden 类成员进行操作(它们是私有的)

    【讨论】:

      【解决方案3】:

      滥用class 充当namespace 会这样做。我不推荐这种模式。

      class hidden_stuff {
      private: // hide base from everyone
          struct base {
              // contents
          };
      public:
          class derived1;
      };
      typedef class hidden_stuff::derived1 derived1;
      
      class hidden_stuff::derived1
          : private hidden_stuff::base {}; // private inheritance required
                  // or hidden_stuff::base is accessible as derived1::base
      

      真正的解决方案(虽然技术上不能满足问题)

      更好的解决方案是使用明确命名的namespace,例如impl::detail::,这将向用户传达他们不应该在内部使用任何类,并停止对重载的任何可能的不良影响之类的。这就是大多数库(甚至标准库实现)对用户“隐藏”类的方式。

      【讨论】:

      • 得知我们不能使用未命名的命名空间来隐藏头文件中的类时,我感到有点惊讶。这似乎是一个完美的工具(除了不允许)。
      • 我喜欢细分成单独的命名空间
      【解决方案4】:

      这是不可能的。

      C++ 要求一个类在它被用作基础时被完全定义,并且由于它的包含机制,任何在类定义时完全定义的东西都必须对所有可以看到定义的人可见所述类。

      C++ 具有防止墨菲(事故)但不能防止马基雅维利(黑客)的机制。


      话虽如此,目的本身是可疑的,我能理解的唯一原因是防止用户依赖您的 Derived 类派生自这个 Fantom 基础这一事实。好吧,私下派生:class Derived: private Fantom {}; 或使用组合代替 class Derived { private: Fantom _fantom; }; 都可以实现这一点。

      【讨论】:

        猜你喜欢
        • 2020-06-20
        • 2014-06-08
        • 2013-08-20
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多