我需要确保在程序执行期间始终至少有一个特定类的实例。 Singleton不会这样做,因为(除其他原因外)我将来可能需要更多实例。一个静态类可能也会这样做但感觉就像走向全局......我也想要一些私有成员,包括函数和变量。
我考虑过将shared_ptr保存在安全的地方,但这似乎是一个粗糙的黑客攻击。
有没有一种标准方法可以做到这一点?
修改
澄清:这不是能够检查实例是否仍然存在的问题。实例必须始终存在。原因是类中有静态成员变量,应保持其状态。
答案 0 :(得分: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;
}
答案 1 :(得分: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
是否有任何实例。
答案 2 :(得分: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
的实例。
答案 3 :(得分: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的共同状态。