首頁  >  文章  >  後端開發  >  為什麼在 C 中透過基底指標刪除派生數組是未定義的行為?

為什麼在 C 中透過基底指標刪除派生數組是未定義的行為?

Barbara Streisand
Barbara Streisand原創
2024-10-31 16:54:02467瀏覽

Why is Deleting a Derived Array via a Base Pointer Undefined Behavior in C  ?

為何存在未定義行為:透過基底指標刪除派生陣列

C 03 標準指定透過基底指標刪除物件陣列是未定義的行為。這是由於要刪除的物件的靜態類型和動態類型之間的差異造成的。

靜態型別與動態型別

指標的靜態型別是程式碼中宣告的型別,而動態型別是指向物件的實際型別。範例程式碼中:

<code class="cpp">struct B { virtual ~B() {} };
struct D : B {};

B* p = new D[20];</code>

p 的靜態型別為 B*,而 *p 的動態型別為 D。

未定義行為

標準規定,在第二種選擇(刪除陣列)中,如果動態類型與靜態類型不同,則行為未定義。這是因為 p 不指向 D 元素數組的開頭。它指向第一個元素的 B 子物件。因此,用delete[]p刪除它;無效。

實作注意事項

在實作中強制執行此規則需要編譯器確定陣列的動態類型,然後將 p 動態轉換為該類型刪除之前。但是,在不使用多態性的情況下,這會帶來不必要的開銷。

多態數組

如果您需要具有多態性行為的數組,可以創建您的數組使用 C 的現有設施自行實現。例如,您可以建立一個類別模板​​來包裝指向派生物件的指標數組:

<code class="cpp">template <typename T>
class PolymorphicArray {
public:
    PolymorphicArray(size_t size) : _size(size), _data(new T*[_size]) {}
    ~PolymorphicArray() { delete[] _data; }
    T*& operator[](size_t index) { return _data[index]; }

private:
    size_t _size;
    T** _data;
};</code>

此類允許您在派生物件數組上使用多態行為,而不會違反標準。

以上是為什麼在 C 中透過基底指標刪除派生數組是未定義的行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn