簡體   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