繁体   English   中英

另一个类中的类对象的 C++ 析构函数

[英]C++ destructor for class object within another class

我正在尝试实现要在另一个Solution类中使用的SegmentTree类。

class SegmentTree ,析构函数实现如下:

~SegmentTree() {
    destruct(root);
};

void destruct(Node* root) {
    if (!root) return;
    
    destruct(root->left);
    destruct(root->right);
    delete root;
    root = NULL;
}

然后,在class Solution ,我们有

class Solution {
private:
    SegmentTree* tree;

public:
    Solution(vector<int>& nums) {
        tree = new SegmentTree(nums);
    }

    //Question: how shall ~Solution() be implemented to free memory of the pointer tree?
};

问题:

  1. 我们是否需要实现析构函数来删除Solution类中的tree指针?
  2. 如果是,将如何实施?

每个new的都必须有一次delete ,否则就会出现内存泄漏。 你可以写一个这样的析构函数:

class Solution {
private:
    SegmentTree* tree;

public:
    Solution(vector<int>& nums) {
        tree = new SegmentTree(nums);
    }
    ~Solution() { 
        delete tree;
    }
};

但是,您需要阅读 3/5 规则( 什么是三的规则? ),因为当一个类管理资源时,只有构造函数和析构函数是不够的。 例如复制上述Solution会导致问题(因为编译器生成的赋值和复制构造函数没有做正确的事情)。 如果可能,您应该努力遵循 0 规则,例如首先不使用指针:

class Solution {
private:
    SegmentTree tree;

public:
    Solution(vector<int>& nums) : tree(nums) {}
};

如果必须动态分配成员,则应使用std::unique_ptr (并且再次使用 0 规则)但不要使用原始指针。

我们是否需要实现析构函数来删除Solution类中的tree指针?

如果使用new创建对象,则需要在使用delete该对象。 所以是的, Solution需要一个析构函数来deletenewtree (就像SegmentTree需要一个析构函数来deletenewNode )。

如果是,将如何实施?

像这样:

class Solution {
private:
    SegmentTree* tree;

public:
    Solution(vector<int>& nums) :
        tree(new SegmentTree(nums))
    {
    }

    ~Solution() {
        delete tree;
    }
};

您可以使用std::unique_ptr自动化,例如:

class Solution {
private:
    std::unique_ptr<SegmentTree> tree;

public:
    Solution(vector<int>& nums) :
        tree(std::make_unique<SegmentTree>(nums))
        //tree(new SegmentTree(nums))
    {
    }
};

无论哪种方式,请注意3 规则

如果一个类需要一个用户定义的析构函数、一个用户定义的复制构造函数或一个用户定义的复制赋值运算符,它几乎肯定需要所有这三个。

因此,您还应该实现(或禁用)复制构造函数和复制赋值运算符,例如:

class Solution {
private:
    SegmentTree* tree;

public:
    Solution(vector<int>& nums) :
        tree(new SegmentTree(nums))
    {
    }

    Solution(const Solution &src) :
        tree(new SegmentTree(*(src.tree)))
    {
    }

    ~Solution() {
        delete tree;
    }

    Solution& operator=(const Solution &rhs) {
        if (&rhs != this) {
            Solution tmp(rhs);
            std::swap(tree, tmp.tree);
        }
        return *this;
    }
};

不过,您可能会考虑简单地摆脱new开始,让编译器为您管理SegmentTree对象:

class Solution {
private:
    SegmentTree tree;

public:
    Solution(vector<int>& nums) :
        tree(nums)
    {
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM