簡體   English   中英

使用沒有虛擬析構函數的基本 class 有什么辦法嗎?

[英]Any way around using a base class that does not have a virtual destructor?

此特定情況適用於 Arduino,但該問題一般適用。 SDK 提供了一個Client class,其他類( WiFiClientEthernetClient等)從該客戶端派生。

在我自己的 class 中,我有一個Client*類型的字段,它可以包含任何這些派生類。 我希望能夠delete clientfield我的 class 中的 clientfield(特別是在其析構函數中),但是因為Client不提供虛擬析構函數,這會導致未定義的行為。

有關解決此問題的方法的任何建議?

我可以修改Client來添加析構函數,但這並不理想,因為任何使用我的代碼的人都必須在他們的系統上進行相同的更改。

您需要做的就是在刪除它之前將指針轉換為它的實際派生類型,例如:

if (isWifiClient)
    delete static_cast<WifiClient*>(clientfield);
else if (isEthernetClient)
    delete static_cast<EthernetClient*>(clientfield);

如果基礎 class 沒有虛擬析構函數,則必須將其從派生類型的指針中刪除。

鑄造是一種選擇:

// No need of `if` as deleting null pointers is noop.
delete dynamic_cast<WifiClient*>(client);
delete dynamic_cast<EthernetClient*>(client);

更好的選擇是使用處理(類型擦除)析構函數的std::shared_ptr

std::shared_ptr<Client> client = std::make_shared<WifiClient>(/*..*/);

請注意,“重構”到std::unique_ptr<Client> (例如,所有權不共享)會導致您的原始問題。

你可以使用shared_ptr嗎? 它在其刪除器中實現動態調度。 但是,分配正確的shared_ptr類型很重要:

shared_ptr<Client> clientfield = make_shared<WifiClient>();

或者

shared_ptr<Client> clientfield = shared_ptr<WifiClient>(new <WifiClient>());

這是錯誤的:

shared_ptr<Client> clientfield(new <WifiClient>());

要使其再次正確,您可以傳遞一個合適的刪除器:

shared_ptr<Client> clientfield(new <WifiClient>(), default_delete<WifiClient>());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM