Giả sử tôi có một lớp học thực hiện hai hay nhiều giao diện COM (chính xác như here):Có sử dụng chuyển đổi ngầm cho một upcast thay vì QueryInterface() hợp pháp với nhiều thừa kế?
class CMyClass : public IInterface1, public IInterface2 {
};
QueryInterface()
phải trả lại con trỏ tương tự cho mỗi yêu cầu của cùng một giao diện (nó cần một sự liệng lên rõ ràng cho điều chỉnh con trỏ thích hợp) :
if(iid == __uuidof(IUnknown)) {
*ppv = static_cast<IInterface1*>(this);
//call Addref(), return S_OK
} else if(iid == __uuidof(IInterface1)) {
*ppv = static_cast<IInterface1*>(this);
//call Addref(), return S_OK
} else if(iid == __uuidof(IInterface2)) {
*ppv = static_cast<IInterface2*>(this);
//call Addref(), return S_OK
} else {
*ppv = 0;
return E_NOINTERFACE;
}
tại đang có hai IUnknown
s trong đối tượng - là một trong những cơ sở của IInterface1
và người kia là cơ sở của IInterface2
. Và .
Hãy giả vờ tôi gọi là QueryInterface()
cho IInterface2
- con trỏ được trả lại sẽ khác với con trỏ được trả về khi tôi gọi QueryInterface()
cho IUnknown
. Càng xa càng tốt. Sau đó, tôi có thể vượt qua các truy xuất IInterface2*
vào bất kỳ chức năng chấp nhận IUnknown*
và nhờ C++ chuyển đổi tiềm ẩn con trỏ sẽ được chấp nhận, nhưng nó sẽ không cùng một con trỏ mà QueryInterface()
cho IUnknown*
sẽ lấy. Thực tế, nếu hàm đó gọi QueryInterface()
cho IUnknown
ngay sau khi được gọi, nó sẽ lấy một con trỏ khác.
Điều này có hợp pháp về mặt COM không? Làm thế nào để xử lý các tình huống khi tôi có một con trỏ đến một đối tượng thừa kế nhân và tôi cho phép một upcast ngầm định?
Thực tế, tôi chưa bao giờ thấy bất kỳ mã nào sử dụng quy tắc nhận dạng COM. Điều đó nói rằng, khác IUnknown * là không hợp pháp - bạn phải chọn một để trở về từ QueryInterface. Về mặt của bạn, nội bộ, C++ sử dụng đối tượng COM thực hiện đối tượng - nếu bạn đang đúc bạn không làm COM anyway, vì vậy bất cứ điều gì bạn đang làm là hợp pháp C++, nhưng không hợp pháp COM. –
@Chris Becke: Tôi đoán danh tính là bắt buộc để triển khai một số chức năng giống như bộ nhớ cache. – sharptooth