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所示。从逻辑上讲,当类的某些部分被定义为不可复制时,如何复制该类?这毫无意义。