QueryInterface是什么?一文带你快速了解它的作用

吉云

今天跟大家聊聊我最近搞的这个`QueryInterface`,一开始我看到这个词的时候,也觉得挺唬人的,但真正上手之后,发现也没那么神秘,就是个接口查询的事儿。

事情是这样的,最近在做一个项目,里面涉及到各种组件之间的交互。一开始大家都是一股脑地往一个对象里塞接口,结果搞到后面,代码那叫一个乱,牵一发而动全身。后来我就寻思,这不行,得想个办法解耦才行。

于是我就开始研究`QueryInterface`。这玩意儿说白,就是让一个组件告诉你,它都实现哪些接口。如果它实现你想要的接口,那就给你返回一个指向该接口的指针,你就可以通过这个指针来调用接口里的方法。如果它没有实现你想要的接口,那就返回个空指针或者错误码,告诉你没这玩意儿。

QueryInterface是什么?一文带你快速了解它的作用

我得明确一点,这个`QueryInterface` 实际上是从 COM (Component Object Model) 那里学来的概念。COM 里一个对象可以实现多个接口,`QueryInterface` 就是用来查询对象是否支持某个特定接口的。

我先从最简单的开始,写一个基类,里面就只有一个 `QueryInterface` 方法。这个方法接收一个接口 ID,然后根据这个 ID 来判断当前对象是否实现该接口。如果实现,就返回指向该接口的指针,否则返回空。

c++

class IUnknown {

public:

virtual void QueryInterface(int interfaceId) = 0;

QueryInterface是什么?一文带你快速了解它的作用

然后,我又定义几个接口,每个接口都有自己的 ID。

c++

class IInterfaceA {

public:

QueryInterface是什么?一文带你快速了解它的作用

virtual void MethodA() = 0;

class IInterfaceB {

public:

virtual void MethodB() = 0;

QueryInterface是什么?一文带你快速了解它的作用

我写一个组件类,让它同时实现 `IInterfaceA` 和 `IInterfaceB`。在这个组件类的 `QueryInterface` 方法里,我根据传入的接口 ID 来判断返回哪个接口的指针。

c++

class MyComponent : public IUnknown, public IInterfaceA, public IInterfaceB {

public:

void QueryInterface(int interfaceId) override {

QueryInterface是什么?一文带你快速了解它的作用

if (interfaceId == 1) { // IInterfaceA 的 ID

return static_cast(this);

} else if (interfaceId == 2) { // IInterfaceB 的 ID

return static_cast(this);

} else {

return nullptr;

QueryInterface是什么?一文带你快速了解它的作用

void MethodA() override {

// 实现 MethodA

void MethodB() override {

QueryInterface是什么?一文带你快速了解它的作用

// 实现 MethodB

我写一个简单的测试程序,来验证 `QueryInterface` 是否能正常工作。

c++

QueryInterface是什么?一文带你快速了解它的作用

int main() {

MyComponent component = new MyComponent();

IInterfaceA interfaceA = static_cast(component->QueryInterface(1));

if (interfaceA != nullptr) {

interfaceA->MethodA();

QueryInterface是什么?一文带你快速了解它的作用

IInterfaceB interfaceB = static_cast(component->QueryInterface(2));

if (interfaceB != nullptr) {

interfaceB->MethodB();

delete component;

return 0;

QueryInterface是什么?一文带你快速了解它的作用

跑一下,没啥问题,`QueryInterface` 确实可以返回正确的接口指针。

这只是个最简单的例子。实际项目中,情况会更复杂一些。比如,接口 ID 的管理,错误处理,内存管理等等。

接口 ID 的管理: 我用的是简单的整数 ID,但实际项目中,最好用 GUID (Globally Unique Identifier) 来保证 ID 的唯一性。

错误处理: `QueryInterface` 返回空指针,只是简单地表示没有实现该接口。但实际项目中,最好返回一个错误码,来更详细地描述错误原因。

QueryInterface是什么?一文带你快速了解它的作用

内存管理: `QueryInterface` 返回的指针,谁来负责释放?这需要仔细考虑,避免内存泄漏。

`QueryInterface` 还是挺有用的,它可以让组件之间的交互更加灵活和解耦。虽然一开始有点难理解,但只要多动手实践,就能掌握它的用法。

希望我的实践记录对大家有所帮助。有啥问题,欢迎留言讨论。

免责声明:由于无法甄别是否为投稿用户创作以及文章的准确性,本站尊重并保护知识产权,根据《信息网络传播权保护条例》,如我们转载的作品侵犯了您的权利,请您通知我们,请将本侵权页面网址发送邮件到qingge@88.com,深感抱歉,我们会做删除处理。

目录[+]