Reputation: 23
This specific case is for Arduino, but the question applies in general. The SDK provides a Client
class, from which other classes (WiFiClient
, EthernetClient
, and others) derive.
In my own class I have a field of type Client*
which can hold any of those derived classes. I'd like to be able to delete clientfield
in my class (specifically in its destructor), but because Client
does not provide a virtual destructor, that would cause undefined behaviour.
Any suggestions for ways to work around this?
I could Modify Client
to add the destructor, but that's not ideal since anyone using my code would have to make that same change on their system.
Upvotes: 0
Views: 104
Reputation: 13387
Can you use shared_ptr
? It implements the dynamic dispatch in its deleter. It is important, though, that you allocate the correct shared_ptr
type:
shared_ptr<Client> clientfield = make_shared<WifiClient>();
or
shared_ptr<Client> clientfield = shared_ptr<WifiClient>(new <WifiClient>());
This would be wrong:
shared_ptr<Client> clientfield(new <WifiClient>());
To make it correct again, you can pass a suitable deleter:
shared_ptr<Client> clientfield(new <WifiClient>(), default_delete<WifiClient>());
Upvotes: 0
Reputation: 217448
If base class doesn't have virtual destructor, you have to delete it from pointer of it derived type.
Casting is one option:
// No need of `if` as deleting null pointers is noop.
delete dynamic_cast<WifiClient*>(client);
delete dynamic_cast<EthernetClient*>(client);
Better alternative is to use std::shared_ptr
which handles the (type-erased) destructor.
std::shared_ptr<Client> client = std::make_shared<WifiClient>(/*..*/);
Note, "refactoring" to std::unique_ptr<Client>
(as ownership is not shared for example) would lead to your original issue.
Upvotes: 0
Reputation: 249293
All you need to do is cast the pointer to its actual derived type before deleting it, for example:
if (isWifiClient)
delete static_cast<WifiClient*>(clientfield);
else if (isEthernetClient)
delete static_cast<EthernetClient*>(clientfield);
Upvotes: 3