[英]In final class derived from base class with virtual destructor, does derived class destructor need “virtual” keyword? Should it have “final” keyword?
[英]Any way around using a base class that does not have a virtual destructor?
此特定情況適用於 Arduino,但該問題一般適用。 SDK 提供了一個Client
class,其他類( WiFiClient
、 EthernetClient
等)從該客戶端派生。
在我自己的 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.