Return a bool callback to indicate whether the calling user should delete itself. Do not remove the client from the callback.
Also, do I need to call a callback at all if data.size == 0 ? Client can check this condition before calling the callback and delete it (or otherwise handle it accordingly).
If the call still needs to be called, perhaps you can avoid changing the return type by simply checking the condition on the client after the call:
void onData(std::string data) { m_callBack->onData(this, data); if (data.size() != 0) { m_totalDataVol += data.size(); } else { delete this; } }
Alternatively, if you really have to allow the callback to delete the client, you will need some way of tracking when the client was deleted, which you can use in the client itself. This means maintaining a link to another object:
class Client{ public: class CallBack { public: virtual void onData(Client* caller, std::string& data) =0; }; Client(CallBack* callback):m_callBack(callback){}, was_deleted(nullptr) virtual ~Client(){ if (was_deleted) *was_deleted = true; } void onData(std::string data) { bool *was_deleted = new bool(); this->was_deleted = was_deleted; m_callBack->onData(this, data); if (! *was_deleted) { m_totalDataVol += data.size(); this->was_deleted = nullptr; } delete was_deleted; } private: CallBack* m_callBack; int m_totalDataVol = 0;
(Please note that the above solution is not thread safe, but it can probably be done like that. Also note that the code above does not compile, since the example code in your question does not work - I tried to match the original code, and it is also possible the principle should be applicable to the real code).
source share