Mã từ thư viện:Xóa đối tượng người gọi một cách an toàn trong một chức năng gọi lại phân khúc
class Client{
public:
class CallBack {
public:
virtual void onData(Client* caller, std::string& data) =0;
};
Client(CallBack* callback):m_callBack(callback){}
virtual ~Client(){}
void onData(std::string data) {
m_callBack->onData(this, data);
m_totalDataVol += data.size();
}
private:
CallBack* m_callBack;
int m_totalDataVol = 0;
}
phân khúc Mã từ ứng dụng:
class AppHandler: public Client::Callback {
void onData(Client* caller, std::string& data) {
/* Some complex logic and check certain conditions*/
delete caller; // Application will crash, due to
// accessing member of deleted object (m_totalDataVol)
}
}
Ngoài Caller đối tượng (instance của lớp Client) được sở hữu bởi ứng dụng và Ứng dụng không hạn chế để xóa ứng dụng đó.
Làm cách nào để khắc phục sự cố này?
kịch bản rất phức tạp: Client
lớp của thư viện cơ sở có thể được kéo dài thêm một thư viện khác (ClientEx
lớp) và các ứng dụng có thể sử dụng thư viện mở rộng (Không phải là thư viện cơ sở)
Nhà phát triển ứng dụng nên biết điều đó. Nhưng trong trường hợp này tôi không thể thêm như vậy trên đầu để phát triển ứng dụng. Điều khác là làm thế nào để thực thi rằng "không xóa đối tượng người gọi". Và đây chỉ là một mã mẫu, nhưng trong thực hiện thực sự nó cần phải thêm logic phức tạp trong hàm "onData" của lớp Client. – Janaka
Xin lỗi, tôi không hiểu phần đầu tiên của nhận xét của bạn. Liên quan đến thứ hai của bạn, điều đó thực sự đủ điều kiện như là câu hỏi của riêng nó. Tôi muốn đề nghị làm cho destructor riêng tư hoặc được bảo vệ. – davmac
Sẽ dẫn đến việc thực hiện cồng kềnh bằng cách làm cho trình tự hủy riêng tư hoặc được bảo vệ. Vì vậy, tôi đang tìm kiếm thiết kế tốt hơn, – Janaka