假设构造函数,析构函数和赋值运算符已正确编写,为什么我不能像这样实现复制构造函数:
MyClass::MyClass(const MyClass &other)
{
this->value = new Value(*(other.value));
}
我看到的大多数例子都是这样的:(因为他们通常处理数组)
MyClass::MyClass(const MyClass &other)
{
Value *temp = new Value;
*temp = *(other.value);
this->value = temp;
}
但是在第一个例子中,如果'new'抛出,'other'不会受到影响,如果Value的copy-constructor抛出,那么在传播异常之前,'new'不会释放已分配的内存吗?
由于这是一个迷你智能指针本身,我特别避免使用std :: unique_ptr和其他智能指针。
答案 0 :(得分:2)
如果Value的copy-constructor抛出,在传播异常之前不会'new'释放已分配的内存吗?
是
没有特别的理由不使用单行方法而不是三行分配版本。
由于您正在编写智能指针,因此以下内容不适用,但在普通类中,您可能会将手动指针管理包装为RAII类型。看起来std::unique_ptr
具有您想要的语义,而make_unique
助手使其非常简单:
#include <memory>
// probably will be added to the standard
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args &&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
class Value {};
class MyClass {
std::unique_ptr<Value> value;
public:
MyClass() : value{make_unique<Value>()} {}
MyClass(MyClass const &other) : value{make_unique<Value>(*other.value)} {}
MyClass &operator= (MyClass const &other) {
value = make_unique<Value>(*other.value);
return *this;
}
// you can also implement assignment from rvalue ref as an optimization
};
答案 1 :(得分:1)
开始枚举有太多问题。我建议你学习三规则:
就像我说的那样,这里适当的解决方案可能会读到
struct MyClass
{
MyClass(const MyClass &other) : value(other.value) {}
private:
OtherClass value;
};
如果value
是某种必须在堆上生存的资源,那么它将被声明为
struct MyClass
{
// ...
private:
std::unique_ptr<OtherClass> value;
};
这样你就不能(很好,很容易)出现所有权语义和内存管理错误。