【问题标题】:how to restrict number of instances of a class in C++ or JAVA?如何限制 C++ 或 JAVA 中类的实例数?
【发布时间】:2013-09-26 19:10:28
【问题描述】:

这个问题是在一次采访中问我的,我试图认为无法回答,我想要一段限制类实例(对象)数量的 C++ 或 JAVA 代码。

【问题讨论】:

  • class Nope { Nope() = delete; }; 将类限制为零实例;)
  • 使用一个包含所创建实例数量的构建器。不过,这并没有考虑到反射。
  • 这个问题毫无意义,除非有线程上下文并限制工作线程的数量。 +1 丹尼尔·弗雷

标签: java c++ class object instance


【解决方案1】:

使用工厂。保留已释放实例数的私有静态计数器。不要让实例受限类的构造函数可见。

【讨论】:

  • @khajvah 工厂是一种用于创建对象的方法,就像工厂是现实生活一样;)
  • 那是你应该用谷歌搜索的东西。那里有很多例子。 google:“java工厂设计模式”和“java工厂方法”。
【解决方案2】:

C++ 中使用static variable 尝试这样的操作:-

struct myclass
{
  myclass()
  {
    if(count == N) { /*throw some exception here!*/ }
    ++count;
  }
  ~myclass()
  {
    --count;
  }
private:
  static std::size_t count = 0;
};

每当创建一个对象时,count 变量就会增加 1。

在 JAVA 中

一个示例实现可能是这样的:-

public class MyClass {
    private static final int LIMIT = 10; //Set this to whatever you want to restrict
    private static int count = 0;
    private MyClass() {}
    public static synchronized MyClass getInstance() {
        if (count < LIMIT) {
            MyClass myClass = new MyClass();
            count++;
            return myClass;
        } 
        return null;
    }
}

【讨论】:

  • 这如何防止任何事情发生? (别介意多线程......)
  • @DanielFrey:- 我只是想说明我们可以检测到创建了多少对象,然后可能会尝试限制它。如果我错了请纠正我!! :)
  • @RahulTripathi 至少让它if( count == N ) throw "limit reached"; 或回答问题的东西。
  • @DanielFrey:- 是的,没错。更新了我的答案!!!谢谢你的建议!!
【解决方案3】:

是的,我们可以将类的实例限制到某个特定的限制。这只是对Singleton Design Pattern的增强

通过将构造函数设为私有,然后创建可见的构造函数方法,我们可以限制实例创建的数量(就像我们在单例设计模式中所做的那样)或回收实例或其他与构造相关的任务。

new x() 永远不会返回 null,但是使用工厂模式,你可以返回 null。

这是相同的 Java 实现:

public class LimitObjectCreationTest {

        public static void main(String[] args) {

        LimitClass obj;
        int i=1;
        while(i<=20)
        {
            obj = LimitClass.getLimInstance();
            i++;
        }
      }
}


class LimitClass {

    /**
     * count of alive instances in JVM  
     */
    public static int objCount = 0;

    /**
     * private constructor
     * increases the objCount static variable on every object creation
     */
    private LimitClass(){
        objCount++;
        System.out.println("instance " + objCount + " created");
    }

    /**
     * static factory method to return LimitClass instance
     * @return instance of LimitClass if not reached to threshold, else returns null
     */
    public static synchronized LimitClass getLimInstance() {
        if(objCount < 3 ){
            return new LimitClass();
        }
        System.out.println("Instance Limit reached. Can not create new Object");
        System.gc();
        return null;
    }

    /**
     * decreases the objCount static variable when JVM runs garbage collection
     * and destroys unused instances
     */
    @Override
    public void finalize()
    {
        System.out.println("Instance destroyed");
         objCount--;
    }
}

输出

instance 1 created
instance 2 created
instance 3 created
Instance Limit reached. Can not create new Object
Instance Limit reached. Can not create new Object
Instance destroyed
Instance Limit reached. Can not create new Object
Instance destroyed
instance 3 created
Instance destroyed
instance 2 created
instance 3 created
Instance Limit reached. Can not create new Object
Instance Limit reached. Can not create new Object
Instance destroyed
Instance Limit reached. Can not create new Object
Instance destroyed
instance 3 created
Instance destroyed
instance 3 created
instance 3 created
Instance Limit reached. Can not create new Object
Instance Limit reached. Can not create new Object
Instance destroyed
Instance Limit reached. Can not create new Object
Instance destroyed
Instance destroyed
instance 1 created
instance 2 created

输出可能因您分配的 JVM 内存而异。

参考:http://codepumpkin.com/use-private-constructor-java/

【讨论】:

    【解决方案4】:

    正确的答案是通过使用工厂方法,如果问题是如何做到这一点?...通过将构造函数设为私有
    一个非常简单的例子是:

    class SingletonClass{ //i.e class with only one instance
    private int a;
    private SingletonClass() // here you see constructor is private
    {}
    private static SingletonClass ref; // this is static reference of the class
    public static SingletonClass getInstance(){ //this is the factory method
    if(ref==null)
    ref=new SingletonClass();
    return ref;
    }
    public void setA(int a){
    this.a = a;
    }
    public int getA(){
    return a;
    }
    }
    class Demo{
    public static void main(String []s){
    SingletonClass s,p; // 2 references for the SingletonClass
    s = new SingletonClass(); /*this will generate compile time error since contructor is                        private */
    s = SingletonClass.getInstance();
    p = SingletonClass.getInstance();
    s.setA(10);
    p.setA(20);
    System.out.println(s.getA()+" "+p.getA());
    }
    }
    

    这里的输出将是 20 20,因为两个引用都指向同一个对象。
    实际上,对象并没有被创建除非构造函数被调用(这就是为什么它被称为构造函数),如果我们将构造函数设为私有,那么我们可以限制对象的创建,然后使用我们可以控制的工厂方法我们想要的创建,在这种情况下它只允许创建 1 个对象。
    仅当没有为该类创建对象时它才会调用构造函数,之后它只会发送引用。
    希望这会有所帮助

    【讨论】:

      【解决方案5】:

      一个非常简单的解决方案

      class XYZ {
      private statuc XYZ[] instance;
      public XYZ[] getInstance(){
      
      if (instance == null) {
      
      instance = new XYZ[4] ; // here I am restricted to make only 4 inxtance
      
      }// if ends here
      return instance;
      
      }// getinstance() ends here
      
      }// class ends here
      

      有了这个功能,我们可以根据需要添加其他方法和变量

      【讨论】:

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