Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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++ 当成员是唯一的\u ptr时,已删除复制构造函数_C++ - Fatal编程技术网

C++ 当成员是唯一的\u ptr时,已删除复制构造函数

C++ 当成员是唯一的\u ptr时,已删除复制构造函数,c++,C++,此代码工作正常: class Test { int* ptr = new int(10); }; int main() { Test o; Test t = o; } 但当我们使用unique_ptr代替raw ptr时,我们会得到一个错误: error: use of deleted function 'Test::Test(const Test&)' 和示例代码: class Test { std::unique_ptr<

此代码工作正常:

class Test
{
    int* ptr = new int(10);
};

int main()
{       
     Test o;
     Test t = o;
}
但当我们使用unique_ptr代替raw ptr时,我们会得到一个错误:

error: use of deleted function 'Test::Test(const Test&)'
和示例代码:

class Test
{
     std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{       
     Test o;
     Test t = o;
}
类测试
{
std::unique_ptr ptr=std::make_unique(1);
};
int main()
{       
试验o;
试验t=o;
}
发生了什么事

发生了什么事

您不能创建第二个测试实例,因为这意味着您需要一个unique_ptr的副本,这是不可能的。唯一的_ptr只能移动。尝试实现一个move-asignment操作符,然后像这样移动
o

class Test
{
public:
    Test() = default;

    Test(Test&& other) noexcept
        : ptr(std::move(other.ptr))
    {
    }

private:
    std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{
    Test o;
    Test t = std::move(o);
}
类测试
{
公众:
Test()=默认值;
测试(测试和其他)无例外
:ptr(std::move(other.ptr))
{
}
私人:
std::unique_ptr ptr=std::make_unique(1);
};
int main()
{
试验o;
测试t=标准::移动(o);
}
如果要复制unique_ptr下面的int,需要定义如下的自定义复制构造函数:

class Test
{
public:
    Test() = default;

    Test(const Test& other)
        : 
    ptr(new int(*other.ptr))
    {

    }

    Test(Test&& other) noexcept
        : ptr(std::move(other.ptr))
    {
    }

private:
    std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{
    Test o;
    Test t = o;
}
class Test
{
private:
    std::shared_ptr<int> ptr = std::make_shared<int>(1);
};

int main()
{
    Test o;
    Test t = o;
}
类测试
{
公众:
Test()=默认值;
测试(常数测试和其他)
: 
ptr(新内部(*其他ptr))
{
}
测试(测试和其他)无例外
:ptr(std::move(other.ptr))
{
}
私人:
std::unique_ptr ptr=std::make_unique(1);
};
int main()
{
试验o;
试验t=o;
}
但是,请注意,指针指向两个不同的int。 如果您想要共享所有权,您必须(并且应该)像下面这样使用shared_ptr:

class Test
{
public:
    Test() = default;

    Test(const Test& other)
        : 
    ptr(new int(*other.ptr))
    {

    }

    Test(Test&& other) noexcept
        : ptr(std::move(other.ptr))
    {
    }

private:
    std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{
    Test o;
    Test t = o;
}
class Test
{
private:
    std::shared_ptr<int> ptr = std::make_shared<int>(1);
};

int main()
{
    Test o;
    Test t = o;
}
类测试
{
私人:
std::shared_ptr ptr=std::make_shared(1);
};
int main()
{
试验o;
试验t=o;
}
发生了什么事

您已经从裸指针切换到强制所有权语义的指针。聪明的人

这就是
unique\u ptr
的真正目的

它强制实施唯一所有权

你不能复制它;只移动它


如果您确实需要
Test
可复制,并且能够共享
int
s,那么您可能正在寻找
shared\u ptr

当然
unique\u ptr
没有复制构造函数,只有移动构造函数。如果要复制
测试
,请使用
共享\u ptr
(或者按照链接答案的建议进行深度复制)。提示在名称中。如果每个人都有一个指针,那么它就不是唯一的指针。事实上,原始代码并不好。它有内存泄漏,切换到
std::unique_ptr
允许编译器防止这种情况(通过不允许您的代码)。@user463035818但这不是指针的副本。您现在有两个不同的指针指向两个不同的对象,这与OP的第一个示例不同。@user463035818我们可能讨论的是答案的不同部分:P@LightnessRacesinOrbit有可能我必须重新加载才能看到编辑。。。现在我对答案很满意。注释deletedI可能会实现这样的复制构造函数:
Test(const-Test&other):Test(){*ptr=*(other.ptr);}
或者
Test(int i=0):ptr(make_unique(i)){}Test(const-Test&other):Test(*(other.ptr)){}
。这样,
Test
的每个实例都可以平等地使用
make\u unique
,并且类中只有一个分配点,而不是让默认构造的实例使用
make\u unique
,而复制的实例使用
new
。但那只是我。无论哪种方式都会“起作用”。@RemyLebeau很有道理。在这种情况下,我可能甚至不考虑实施它,因为复制是有限的。谢谢你的回答。但是我在哪里可以找到这样的规则:当类具有唯一的\u ptr成员时,从类中删除复制构造函数?编译器必须调用被删除的唯一的\u ptr的复制构造函数。MSVC发出以下错误
“Test::Test(const Test&”):试图引用已删除的函数
@keyborys请参见:@keyborys,如Nathan所示。从逻辑上讲,当类的某些部分被定义为不可复制时,如何复制该类?这毫无意义。