[英]Delete Inherited class Pointer Array in C++
我有一個 A 類,例如:
class A
{
int a;
}
而且,我還有 B 類繼承了 A 類:
class B : public A
{
int b;
public:
static A** ReturnAPtrArray(int size);
}
然后,我使 Array 在 B 類中具有 A 類指針。
A** B::ReturnAPtrArray(int size)
{
A** array = new A*[size];
for(int i = 0; i< size; i++)
{
array[i] = new A();
}
return array;
}
在主函數中,我調用了 B 類的 ReturnAPtrArray() 函數。
void main(void)
{
int size = 100;
A** aptrArray = B::ReturnAPtrArray(size);
--------Do Something
delete[] aptrArray;
}
這個主函數會導致內存泄漏。 所以我刪除了這樣的每個指針:
void main(void)
{
int size = 100;
A** aptrArray = B::ReturnAPtrArray(size);
--------Do Something
for(int i = 0; i< size; i++)
{
delete aptrArray[i];
}
delete[] aptrArray;
}
修改main func后,內存泄漏消失。
如果我想釋放內存,我應該刪除指針數組中的所有指針嗎?
還有其他選擇嗎?
如果我想釋放內存,我應該刪除指針數組中的所有指針嗎?
是的你應該
delete[]
只刪除它自己的數組。 由於您有一個指針數組,您必須單獨刪除每個指針元素。
至於其他選項,您可以使用智能指針。
例子:
#include <memory>
#include <vector>
int main()
{
std::vector<std::shared_ptr<A>> array;
for(int i = 0; i < 100; i++)
{
array.push_back(std::make_shared<B>());
}
}
當數組超出范圍時,它會自行刪除
區分多態所有權和多態使用很重要。 多態所有權是指您想要擁有未知類型的事物(或許多事物)。 多態使用是當你不知道它是什么時想要操縱它。 你的例子並沒有真正說明你為什么使用繼承,所以我會解釋兩者。
如果您只創建 B,只需將它們聲明為 B。 如果您想將一組 B 傳遞給一個不知道它們是 B 的函數,只需創建一個 B 向量並將它們作為指向 A 的指針傳遞。
像這樣 ...
std::vector<B> myBs(5); // create 5 default B's
for (const auto& thisB: myBs) Fn(&thisB); // cast a ptr-to-B to a ptr-to-A
像這樣保持簡單會讓你的生活更簡單,因為這段代碼是類型安全的。
另一方面,如果您想擁有一個可能是 B 或可能不是,但絕對繼承自 A 的事物列表。使用類似這樣的東西。
std::vector<std::unique_ptr<A>> my_maybe_bs_might_not;
這種模式可能表面上看起來更簡單,但它有很多問題。 例如,您必須使用必須使用虛擬析構函數。 這反過來又調用了 3/5規則。 簡單地說,如果編譯器不知道一個東西是什么,你必須告訴它如何移動/復制它。 如果不這樣做,編譯器可能會做錯事。
一個更簡單的(假設你有 C++17)多態所有權的方案是使用一個變體。 當你使用一個變體時,你必須列出它可能是的所有東西,這可以包括智能指針。
using MaybeB = std::variant<std::unique_ptr<B>, std::unique_ptr<C>>;
std::vector<MaybeB> my_maybe_bs_might_not;
這種模式允許編譯器為您生成所有正確的代碼,同時使添加新類變得簡單。 唯一的缺點是因為你必須列出你可能想要擁有的所有東西。 這對於庫級系統來說是一個糟糕的選擇,庫的用戶可能想要編寫他們自己的類(從 A 派生)並將其添加到您的列表中。
一般建議是盡可能選擇最簡單的方案,這通常意味着避免多態所有權,除非確實需要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.