【问题标题】:How to ensure a specific class only can create an instance of another class?如何确保特定类只能创建另一个类的实例?
【发布时间】:2017-05-29 16:32:59
【问题描述】:

如何限制类的实例化仅在特定类中?

我不想将它限制在单个文件中,所以匿名命名空间不适合我。

请注意,我想让被限制类的声明对整个世界可见,只是全世界只有一个特定的候选人可以实例化它。

我怎样才能做到这一点?

【问题讨论】:

  • 将单独的类作为friend 与非公共可构造类的private 构造函数结合使用,应该可以工作。
  • " 我想让被限制类的声明对全世界可见,只是全世界只有一个特定的候选者只能实例化和访问它" 那么,为什么显示如果你不能触摸它?我错过了什么吗?
  • 你想要一个单例模式吗?实例化一次并为所有事情使用一个实例?
  • 可能是抽象工厂模式。
  • @Mariners 不,我没有建议。您从哪里读到我建议制作一切 private?我的建议是:privateconstructor,这正是最佳答案所建议的,举个例子。

标签: c++ c++11


【解决方案1】:

使用friends!使班级Foo 成为班级Bar 的朋友意味着Foo 可以访问Bar 的私人成员。如果将构造函数设为私有,则只有 Foo 能够创建 Bar 的实例。

struct restricted_t {
    friend struct allowed_t; // allow 'allowed_t' to access my private members
private:
    // nobody can construct me (except for my friends of course)
    restricted_t() = default;
};

struct allowed_t {
    restricted_t yes; // ok
};

struct not_allowed_t {
    restricted_t no; // not ok
};

int main() {
    allowed_t a; // ok, can access constructor
    not_allowed_t b; // error, constructor is private
}

【讨论】:

    【解决方案2】:

    您可以采用passkey pattern(借鉴自 Rakete1111 的示例):

    class pass_key { friend class allowed_t; pass_key() {} };
    
    struct restricted_t
    {
      restricted_t(pass_key);
    };
    
    class allowed_t
    {
    public:
      allowed_t() : yes(pass_key()) {}  // ok, allowed_t is a friend of pass_key
    
    private:
      restricted_t yes;
    };
    
    class not_allowed_t
    {
    public:
      not_allowed_t() : no(pass_key()) {}  // not ok, pass_key() is private
    
    private:
      restricted_t no;
    };
    
    int main()
    {
      allowed_t a;     // OK, can access constructor
      not_allowed_t b; // ERROR, only a friend of the key
                       // class has access to the restricted
                       // constructor
    }
    

    与使restricted_t 成为allowed_t 的朋友相比,该模式允许更细粒度的访问控制,并且避免了复杂的代理模式。

    【讨论】:

    • 这是一个不错的解决方案。非常感谢:)。
    • @Mariners 不客气。另请查看模式的Matthieu's description 以了解实现细节。
    猜你喜欢
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    • 2012-07-07
    • 2010-12-28
    • 2020-10-16
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    相关资源
    最近更新 更多