使用std::unique_ptr::reset
,您可以轻松地将实例恢复到新的状态。
Pre-C ++ 11,为了实现类似的行为,我看到很多类定义了一个Reset()
方法,它重置了所有内部成员。但是现在,我认为只需使用构造函数和析构函数并reset
unique_ptr
到类的新实例即可。对于为什么您仍然偏好Reset()
方法,我是否缺少任何好处,或者我们应该始终只使用unique_ptr
和reset
将其用于新实例,只要我们想“重置“我们的班级?
我能想到的唯一好处就是你保存了有时很昂贵的分配/删除。 当然,成本是维护Reset()函数并确保其与其他代码更改保持同步的复杂性。
是吗?这只是一个复杂性和性能问题?答案 0 :(得分:4)
这是将类的状态重置为默认构造状态的非常好的通用方法:
// Previously constructed MyClass myvalue = ...
myvalue = MyClass{};
这涉及两个操作:
理想情况下,这些都应该便宜。
答案 1 :(得分:0)
我能想到的唯一好处就是你省了一个 分配/删除有时可能很昂贵
不仅可能昂贵的分配,而且可能的内存碎片,糟糕的局部性(感谢@Cris在我脑海中搜索的术语),在频繁重置期间,最终会引入巨大的性能问题。
unique_ptr
并不意味着重置您的实例状态。
unique_ptr::reset
重置unique_ptr
的所有权,结果调用析构函数" old"实例。
因此,这与您的实例Reset
方法完全不同。
如果重置
您没有实例化新内存 - >亲
可能会重复使用相同的内存而不会丢弃它,因此请保持数据的对齐和紧密包装(取决于 你实施Reset
方法的方式) - >亲
非安全内存管理,导致内存泄漏 - >缺点
如果是unique_ptr
所有专业和缺点自然是有争议的,取决于具体的实施和实际要求。
答案 2 :(得分:0)
分配/删除是一个成本,但是还有通过指针访问对象的额外间接级别的成本。例如,较差的数据位置。
也可以在只有引用或指针的上下文中调用Reset()
函数。应该知道对象由unique_ptr
管理的唯一对象是所有者。在其他情况下,最好使用引用或指针。
但只要你知道成本并且只有主人想要重置,我就不会发现这样做有什么不妥。
当然,这在C ++ 11中并不新鲜,使用堆分配的对象始终可以做到这一点。这只是unique_ptr
如何让生活更轻松的一个例子。
答案 3 :(得分:0)
我认为你在这里搞混合了。
像unique_ptr
这样的{p> shared_ptr
是代表所有权的构造。
除非您自己提供复制构造函数和复制赋值运算符,否则使用unique_ptr
意味着您的类既不能复制也不能复制分配。
这可能是额外的工作。
因此,如果您仍想提供重置方法但不想手动重置每个成员变量的代码,您可以执行以下操作:
MyClass::Reset()
{
this->~MyClass();
new(this) MyClass();
}
会将您的实例重置为默认创建状态。
这种方法的缺点是
vector
成员及其在堆上的相关内存,而不是重用。实际上你也可以实现Reset
之类的
MyClass::Reset()
{
*this = MyClass();
}
虽然这可能比以前的解决方案慢。