2

假设构造函数、析构函数和赋值运算符写得正确,为什么我不能像这样实现复制构造函数:

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 的复制构造函数抛出,“new”不会在传播异常之前释放分配的内存吗?

由于这是一个迷你智能指针本身,我特别避免使用 std::unique_ptr 和其他智能指针。

4

2 回答 2

2

如果 Value 的复制构造函数抛出,在传播异常之前不会“新”释放分配的内存吗?

是的。

没有特别的理由不使用单行方法而不是三行赋值版本。


由于您正在编写智能指针,因此以下内容不适用,但在普通类中,您可能会将手动指针管理包装成 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
};
于 2013-03-18T02:27:44.310 回答
1

问题太多,不一一列举。我建议你学习三法则:

就像我说的,这里的正确解决方案可能是

struct MyClass
{
     MyClass(const MyClass &other) : value(other.value) {}

    private:
     OtherClass value;
};

如果value是某种必须存在于堆上的资源,那么它将被声明为

struct MyClass
{
    // ...
    private:
       std::unique_ptr<OtherClass> value;
};

这样你就不会(嗯,很容易)在所有权语义和内存管理上出错。

于 2013-03-18T02:21:17.033 回答