Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调用动态分配的类';复制构造函数中的复制构造函数?_C++_Copy Constructor - Fatal编程技术网

C++ 调用动态分配的类';复制构造函数中的复制构造函数?

C++ 调用动态分配的类';复制构造函数中的复制构造函数?,c++,copy-constructor,C++,Copy Constructor,假设构造函数、析构函数和赋值运算符编写正确,为什么我不能像这样实现复制构造函数: MyClass::MyClass(const MyClass &other) { this->value = new Value(*(other.value)); } 我看到的大多数示例都是这样做的:(因为它们通常处理数组) 但在第一个示例中,如果“new”抛出,“other”不受影响,如果Value的复制构造函数抛出,“new”不会在传播异常之前释放分配的内存吗 由于这是针对小型智能指针本

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

MyClass::MyClass(const MyClass &other)
{
    this->value = new Value(*(other.value));
}
我看到的大多数示例都是这样做的:(因为它们通常处理数组)

但在第一个示例中,如果“new”抛出,“other”不受影响,如果Value的复制构造函数抛出,“new”不会在传播异常之前释放分配的内存吗


由于这是针对小型智能指针本身的,因此我特别避免使用std::unique_ptr和其他智能指针。

有太多问题需要开始枚举。我建议你学习三条规则:

正如我所说,这里的正确解决方案可能是

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

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

struct MyClass
{
    // ...
    private:
       std::unique_ptr<OtherClass> value;
};
struct MyClass
{
// ...
私人:
std::唯一的ptr值;
};
这样,您就不会(很容易)在所有权语义和内存管理方面出错

如果Value的copy构造函数抛出,在传播异常之前,“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
};
#包括
//可能会添加到标准中
模板
std::unique_ptr使_唯一(Args&&…Args){
返回std::unique_ptr(新的T(std::forward(args)…);
}
类值{};
类MyClass{
std::唯一的ptr值;
公众:
MyClass():值{make_unique()}{}
MyClass(MyClass常量和其他):值{make_unique(*other.value)}{
MyClass和运算符=(MyClass常量和其他){
值=使_唯一(*其他值);
归还*这个;
}
//您还可以从右值引用实现赋值作为优化
};

为什么首先动态分配
?你试图以高昂的代价赋予它值语义,但也做得不对?值是指向另一个类的指针。也许名称“Value”是个错误的词-我应该使用更通用的“Data”或“OtherClass”。如果我“也做错了”,这就是为什么我要问这个问题,因为我不知道我做得对不对。@JaminGrey实现复制构造函数没有什么错,正如你所展示的。如果复制构造函数抛出。第二个例子,事实上,如果值的赋值运算符抛出,可能会给您留下泄漏的内存。@WhozCraig不是用“new”清理的吗?这就是《裁判官公告》所暗示的,也就是说,除非我误读了一些东西,我可能是误读了。new不会捕捉到它正在分配的类的构造函数或复制构造函数中抛出的异常吗?@JaminGrey是的,你完全正确,我不得不通过帖子和一些标准引用来确定,但他(帕累托人)和你是完全正确的;这就是它应该表现的方式,因此我坚定地站在选项的阵营里#1=PI我在问一个关于三法则的问题,我不理解其中的一部分。我在原来的问题中提到了这一点。不过,提供std::unique_ptr是一个很好的建议!但在这种情况下,我特别避免使用它。是的,因为“其他”是常量,所以我说它不会受到影响-这部分不是问题,而是陈述。=)谢谢你回答实际问题!我已经有了一个make_unique助手,并且在我的代码中通常使用std::unique_ptr和std::shared_ptr,我应该提到我是专门为这个特定类避免使用它的。哎呀。
#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
};