【发布时间】:2014-06-17 22:47:59
【问题描述】:
问题
考虑这个简单的类:
struct C {
C(const char* name) : name(name) {
cout << "constructing " << name << endl;
}
~C() {
cout << "destructing " << name << endl;
}
string name;
};
我想要一个指向这个类的实例的指针,它通常会被另一个实例替换。但是,我希望在创建新实例之前 销毁当前实例。
错误的例子
如果我以正常方式使用unique_ptr,这将不起作用:
unique_ptr<C> c( new C("the first one"));
c.reset(new C("the second one"));
(不需要的)输出:
构建第一个
构建第二个
破坏第一个
摧毁第二个
丑陋的例子
可以达到预期的效果如下:
unique_ptr<C> c( new C("the first one"));
c.reset(); // explicitly destruct the first one first
c.reset(new C("the second one"));
输出:
构建第一个
破坏第一个
构建第二个
摧毁第二个
尝试的解决方案
这是我尝试创建具有这种行为的智能指针。 这样的智能指针是否已经存在?
template<typename Resource>
class ResourceManager {
public:
ResourceManager() {}
template<typename... Arguments>
ResourceManager(Arguments&&... args) {
replace<Arguments...>(std::forward<Arguments>(args)...);
}
template<typename... Arguments>
void replace(Arguments&&... args) {
resource.reset();
resource.reset(new Resource(std::forward<Arguments>(args)...));
}
private:
unique_ptr<Resource> resource;
};
template<typename Resource, typename... Arguments>
ResourceManager<Resource> make_resource_manager(Arguments... args) {
return ResourceManager<Resource>(args...);
}
int main() {
//ResourceManager<C, const char*> r("first1");
auto r = make_resource_manager<C>("first1");
r.replace("second1");
}
输出:
构建第一个
破坏第一个
构建第二个
摧毁第二个
编辑:将“参数...”模板移至函数级别。
编辑 2:现在正确转发“参数”。
【问题讨论】:
-
为什么不分配一个新的呢? ptr = make_unique
(); -
@paulm:因为他不希望两个同时存在。
-
问题是为什么你不能有两个实例,你也不能重用现有的......这在某种程度上是一种脆弱的方法,你最终会得到 根本没有资源。
-
@DavidRodríguez-dribeas 我正在各种类似 istream 的对象 (ZipEntries) 之间切换,这些对象源自单个 ZipFile 对象(表示具有多个条目的 zip 存档)。在打开一个新的之前,我必须确保之前的 ZipEntry 被销毁。
-
在我看来这是一个忽略实际问题的线程问题。
标签: c++ smart-pointers unique-ptr resourcemanager resource-management