智能指针如何影响 5 规则?
Posted
技术标签:
【中文标题】智能指针如何影响 5 规则?【英文标题】:How do smart pointers affect the rule of 5? 【发布时间】:2020-04-15 07:57:19 【问题描述】:我了解到,当您在类中使用指针时,您应该实现规则 5。如果您不使用指针,那么您可以,实际上更可取的是使用默认值。但是,这如何与智能指针一起使用?例如,包含int*
的类可能如下所示:
class A
private:
int *num_;
public:
explicit A(int* num) : num_(num)
~A()
delete num_;
A(const A &other)
if (this != &other)
num_ = other.num_;
A(A &&other) noexcept
if (this != &other)
num_ = other.num_;
A &operator=(A &other)
if (this == &other)
this->num_ = other.num_;
return *this;
A &operator=(A &&other) noexcept
if (this == &other)
this->num_ = other.num_;
return *this;
;
;
但是如果我们使用智能指针,这样做就足够了吗?
class B
private:
std::unique_ptr<int> num_;
public:
explicit B(int num) : num_(std::make_unique<int>(num)) ;
;
【问题讨论】:
请注意,示例不会做同样的事情,因为第二个示例将隐式删除复制构造函数和赋值运算符,因为std::unique_ptr
不可复制
啊,这很有道理。那么我应该使用std::shared_ptr
吗?
这取决于您是否希望 B
可复制(A
和 B
都是可移动的)
@CiaranWelsh 这不应该是您选择智能指针类型的理由。而是:您是否需要共享所有权。在A
中没有共享所有权(至少不正确;)
我想这是一个错字:if (this == &other)
【参考方案1】:
是的,这就足够了。唯一指针确实管理内存。但是,您的两个类的行为会有所不同,因为无法复制 std::unique_ptr
,因此不会有编译器生成的复制构造函数,也不会为 B
赋值。
还请注意,您实现了规则 5 的所有方法,但不正确。如评论中所述,复制 A
将导致两个实例具有相同的指针并在销毁时将其删除。实际上,正确理解这一点就是关于 3/5 规则的全部意义,以及为什么你应该更喜欢 0 规则。
【讨论】:
【参考方案2】:如果您使用智能指针(或任何 std:: 容器),类默认析构函数将调用智能指针(和容器)的析构函数。 有关此主题的更多信息:Why doesn't the C++ default destructor destroy my objects?
【讨论】:
【参考方案3】:那些有不同的行为。 A
可以复制,B
只能移动。
注意你对A
的实现是不安全的,它可能导致泄漏和未定义的行为。
同类比较是delete
A
的副本
class A
private:
int *num_;
public:
explicit A(int num) : num_(new int(num))
~A()
delete num_;
A(const A &other) = delete;
A(A &&other) noexcept
: num_(std::exchange(other.num, nullptr))
A &operator=(const A &other) =delete;
A &operator=(A &&other) noexcept
swap(num_, other.num_);
return *this;
;
;
class B
private:
std::unique_ptr<int> num_;
public:
explicit B(int num) : num_(std::make_unique<int>(num)) ;
;
或者定义B
的副本
class A
private:
int *num_;
public:
explicit A(int num) : num_(new int(num))
~A()
delete num_;
A(const A &other)
: A(other.num)
A(A &&other) noexcept
: num_(std::exchange(other.num, nullptr))
A &operator=(const A &other)
*num_ = *other.num;
return *this;
A &operator=(A &&other) noexcept
swap(num_, other.num_);
return *this;
;
;
class B
private:
std::unique_ptr<int> num_;
public:
explicit B(int num) : num_(std::make_unique<int>(num)) ;
~B() = default;
B(const B & other) : B(*other.num_)
B(B && other) = default;
B& operator=(const B & other) *num_ = *other.num_
B& operator=(B && other) = default;
;
【讨论】:
以上是关于智能指针如何影响 5 规则?的主要内容,如果未能解决你的问题,请参考以下文章