首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >智能指针如何影响5的规则?

智能指针如何影响5的规则?
EN

Stack Overflow用户
提问于 2020-04-15 15:57:20
回答 3查看 355关注 0票数 1

我了解到,当你在一个类中使用指针时,你应该实现5的规则。如果你不使用指针,那么你是可以的,事实上,使用缺省值是最好的。然而,这如何与智能指针一起工作呢?例如,包含int*的类可能如下所示:

代码语言:javascript
复制
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;
    };


};

但是如果我们使用智能指针,仅仅这样做就足够了吗?

代码语言:javascript
复制
class B {
private:
    std::unique_ptr<int> num_;

public:

    explicit B(int num) : num_(std::make_unique<int>(num)) {};

};
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-04-15 16:05:06

是的,这就足够了。唯一指针确实管理内存。但是,您的两个类的行为将不同,因为std::unique_ptr不能被复制,因此不会有编译器生成的复制构造函数,也不会为B赋值。

还要注意,您为规则5实现了所有方法,但并不正确。正如在注释中提到的,复制A将导致两个实例具有相同的指针,并在销毁时将其删除。实际上,这是关于3/5规则的全部要点,也是为什么你应该更喜欢0规则的原因。

票数 3
EN

Stack Overflow用户

发布于 2020-04-15 16:04:41

如果使用智能指针(或任何std::容器),则类的默认析构函数将调用智能指针(和容器)的析构函数。有关此主题的更多信息,请单击此处:Why doesn't the C++ default destructor destroy my objects?

票数 1
EN

Stack Overflow用户

发布于 2020-04-15 16:16:06

它们有不同的行为。可以复制A,只能移动B

注意:您的A实现是不安全的,它可能会导致泄漏和未定义的行为。

delete A的复制品与同类产品的比较

代码语言:javascript
复制
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的副本

代码语言:javascript
复制
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;

};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61223944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档