2

我需要确保在程序执行期间始终存在某个类的至少一个实例。单身人士不会这样做,因为(除其他原因外)我将来可能需要更多实例。一个静态类也可以,但这感觉就像走向全球......我还想要一些私有成员,包括函数和变量。

我想过将 shared_ptr 保存在安全的地方,但这似乎是一个粗略的黑客攻击。

有没有标准的方法来做到这一点?

编辑

澄清一下:这不是能够检查实例是否仍然存在的问题。实例必须始终存在。原因是类中有静态成员变量,应该保持它们的状态。

4

4 回答 4

1

我总是使用内部静态计数器来实现这一点,该计数器在构造函数中递增并在析构函数中递减。

是的,绝对你检查“至少一个实例”的方法应该是静态的。

更新:好的,我在这里看到答案中的错误,所以我发布了我的答案:

class Test
{
private:
  static int m_count;
public:
  Test() { ++m_count; }
  Test(const Test&) { ++m_count; }

  ~Test()
  {
    --m_count;
  }

  static bool hasInstance()
  {
    return (m_count > 0);
  }
};

int Test::m_count = 0;

int main()
{
    return 0;
}
于 2013-04-18T15:54:40.827 回答
1

使用静态成员并将其设置在构造函数/析构函数中:

class Test
{
  static int i;
public:
  Test()
  {
    i++;
  }

  Test(const Test &t) // It's suspicious 
  {
    i++;
  }

  ~Test()
  {
      i--;
  }

  static bool hasInstance()
  {
    return i>0;
  }
};

static int Test::i = 0;

然后,您知道是否Test有任何实例。

于 2013-04-18T15:55:32.720 回答
1

一种包含所有实例集合的工厂类怎么样?

就像是:

template<typename T>
class least_one_factory
{
    static std::vector<T> instances_;

public:
    least_one_factory()
    {
        // Make sure there is an instance of `T` in our collection
        instance_.push_back(T());
    }

    T& get()
    {
        return instances_.front();
    }

    T& get(int n)
    {
        return instances_.at(n);
    }

    T& create()
    {
        instances_.push_back(T());
        return instances_.back();
    }

    int count() const
    {
        return instances_.size();
    }

    operator T&()
    {
        return get();
    }
};

template<typename T>
std::vector<T> least_one_factory<T>::instances_;

现在你可以这样做:

struct some_class {};

least_one_factory<some_class> some_class_factory;

该变量some_class_factory将包含至少一个some_class. 你可以得到它some_class_factory.get()。如果some_class_factory是全局变量,则在调用some_class之前加载程序时将创建的实例main

于 2013-04-18T16:01:00.867 回答
1

我需要确保在程序执行期间始终存在某个类的至少一个实例。

所以我想解决方案从决定谁负责存储它开始。

您可以:将其存储在类内部(静态)或将其返回给调用者/客户端上下文(并依赖客户端上下文来保留它)。由于您说“单身人士不会做”,因此解决方案应如下所示:

class TheClass
{
public:
    // this doesn't have to be a std::shared_ptr<WithContext>
    // and probably shouldn't be (see below)
    typedef <implementation-defined> GlobalContext;

    GlobalContext InitContext(); // return instance
};

void main( /* ... */ )
{
    // do this before any code that uses TheClass instances
    auto global_execution_context = TheClass::InitContext();

    // rest of your application code goes here
}

我想过将 shared_ptr 保存在安全的地方,但这似乎是一个粗略的黑客攻击。

你认为它的缺点是什么?如果是因为它是一个模糊的依赖项,您可以为其添加测试,或者在上下文被删除/影响/不存在时抛出异常。您还可以在 TheClass 的构造函数中请求对您的上下文的引用。

您不应该让 GlobalContext 成为 std::shared_ptr 但它是自己的类型的原因是,这就是您的要求实际相当于:

您需要一种(新)类型的对象来保持实例之间的 TheClass 的共同状态。

于 2013-04-18T16:34:37.087 回答