首页
学习
活动
专区
圈层
工具
发布

COM聚合技术中的QueryInterface

首先,我们要验证的第一个问题是,对于多重继承,将派生类的指针强制转换成基类类型之后,是否就会出现和上述问题一些样的现象?...多重继承的情况下,在类的结构中会有多个基类的虚函数表,比如上例,Derived类继承了Base1和Base2,那么其中就有2个虚函数表,在我们调用虚函数时,会从对应的虚函数表中进行查询: 在多重继承中...,派生类中对于基类中虚函数表和各成员的排列顺序与继承的顺序一致,最后才是派生类自己的成员: 由于这样的数据结构,在进行强制转换时,实际上是将虚函数表的指针传出,故转换后指针的值发生了变化。...,根据CA的继承关系,转换后的指针发生了变化,该指针实际上是NondelegatingUnknown的虚函数表的指针,因此,外部组件CB使用m_pUnknownInner查询时,实际上使用的是NondelegatingUnknown...NondelegatingUnknown和Unknown在结构上是相同的,在传递给m_pUnknownInner时,发生了隐式转换,所以根据函数在内存中的位置,可以找到对应函数,而且,虚函数的调用是运行时确定

1.3K20

有关QueryInterface函数

函数 QueryInterface函数} 多重继承及类型转换。...通常将一种类型的指针转换为另一种类型并不会改变它的值。为了支持多重继承,某些情况下,C++必须改变类指针的值。...假如一个类定义如下: class CA: public IX,public IY{…}; 由于CA同时继承了IX,IY因此可以使用IX或IY指针的地方均可以使用指向CA的指针。...QueryInterface函数 foo需要一个指向合法的IX的虚拟函数表的指针; bar需要一个指向合法的IY的虚拟函数表的指针; 当然IX和IY的虚拟函数表的内容是不一样的。...因此编译器将同一指针传给foo和bar是不可能的,它必须对CA的指针进行修改以便他指向一个合适的vtbl指针。 下图显示了CA对象的内存结构。

64320
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    QueryInterface详解 COM

    QueryInterface 接口查询 IUnknown: 所有的COM接口均需要继承IUnknown接口。...,我们将pIX初始化为NULL,这是一种比较好的编程习惯,但由于QueryInterface是由程序员而不是由系统实现的,因此在查询失败的时候,将此指针置为NULL....=(IY*)this; 将this指针进行类型转换将会导致其值的改变,这一点主要是由于C++的实现方式。 一般在将this指针赋值给某个void指针时候,应先将其转化为合适的类型。...多生继承及类型转换 通常将一种类型的指针转化成为另外一种类型,并不会改变它的值,但是为了支持多重继承,在某些情况下,C++必须改变类指针的值。许多C++程序员并不清楚多重继承的此种负面效果。...例如假定有一个类CA定义如下: Class CA:public IX,public IY{}; 由于CA同时继承了IX和IY,因此在可以使用IX或者IY指针的地方均可以使用指向CA的指针。

    1.5K20

    浅谈java中extends与implements的区别

    extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法;implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用.   ...extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口 来实现,这样就要用到implements,继承只能继承一个类...a.i,a.f()是合法的,而a.j,a.g()非 法。...a,这就是上传(upcast),是安全的。...因此你可以理解成接口是子类实现其方法声明而不是继承其方法。但是一般类的方法可以有方法体,那么叫继承比较合理。引入包可以使用里面非接口的一切实现的类。

    9K93

    代码重用

    使用多个基类的继承被称为多重继承,例如: class A{}; class B{}; class C : private A,private B{ //多重继承 ... }; 2....派生类的私有成员 基类的私有成员变成 只能通过基类的接口访问 只能通过基类接口访问 只能通过基类接口访问 能否隐式向上转换 是 是(但只能在派生类中) 否 (注:这里的隐式向上转换只意味着无需进行显式类型转换...多重继承 多重继承描述的是有多个直接基类的类,与单继承一样,公有多重继承表示的都是is-a的关系。而私有多重继承和保护多重继承表示的是has-a的关系。...Base的构造函数,是合法的,但是对于非虚基类,则是非法的。)...如果类有间接虚基类,则除非只使用该虚基类的默认构造函数,否则必须显式地调用该虚基类的某个构造函数。

    92740

    【C++特殊工具与技术】优化内存分配(六):运行时类型识别

    其核心特性是: 仅适用于多态类型(即类包含至少一个虚函数) 转换失败时,指针类型返回nullptr,引用类型抛出std::bad_cast异常 支持三种转换方向:向上转换(Upcast)、向下转换(Downcast...(失败抛出std::bad_cast) Derived& d_ref = dynamic_cast(base_ref); 2.2 转换场景详解 场景 1:向上转换(Upcast) 向上转换...{ cout << "Derived::func()" << endl; } }; int main() { Derived d; Base* base_ptr = &d; // 隐式向上转换...); upcast_ptr->func(); // 输出:Derived::func()(多态调用) return 0; } 场景 2:向下转换(Downcast) 向下转换(基类指针...name: " << demangle(ti.name()) << endl; return 0; } 四、type_info类详解 4.1 类定义(C++ 标准摘要) type_info类由编译器隐式生成

    8910

    Java基础12 类型转换与多态

    我们之前使用类创造新的类型(type),并使用继承来便利我们创建类的过程。我将在这一讲中深入类型,并介绍多态(polymorphism)的概念。...Java是一种强类型(strongly typing)语言,它会对类型进行检查。如果我们错误的使用类型,将造成错误。 ?  ...Java可以对基本类型的变量进行类型转换。...基本类型转换 upcast与多态 在Java中,引用也可以进行类型转换,但是有限制。 ? 我们可以将一个衍生类引用转换为其基类引用,这叫做向上转换(upcast)或者宽松转换。...Java告诉我们,一个衍生类对象可以当做一个基类对象使用,而Java会正确的处理这种情况。 比如下面的继承关系: ? 我们可以说用杯子(Cup)喝水(drinkWater)。

    75290

    Effective C++笔记

    在资源管理类中提供对原始资源的访问 APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理的资源”的办法 对原始资源的访问可能经由显示转换或隐式转换。...一般而言显示转换比较安全,但隐式转换对客户比较方便 16. 成对使用new和delete时,要采取相同形式 如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。...明智而审慎地使用多重继承 多重继承比单一继承复杂。它可能导致新的歧义性,以及对virtual继承的需要 virtual继承会增加大小、速度、初始化(及赋值)复杂度等等成本。...如果virtual base classes不带任何数据,将是最具使用价值的情况 多重继承的确有正当用途。...需要类型转换时请为模板定义非成员函数 当我们编写一个class template,而它所提供的“与此template相关的”函数支持“所有参数的隐式类型转换”时,请将那些函数定义为“class template

    1K20

    如何升级Truffle到v5.0.0使用Solidity v0.5.0新特性?1, 摘要2,操作步骤3, Solidity 0.5.0新特性4,参考

    3.2 Solidity 0.5.0 丢弃/禁止使用的特性 构造函数必须用constructor关键字定义,而不是与合约同名的函数 不允许调用的函数 callcode (推荐使用delegatecall...的转换(显式或隐式) 不允许十六进制数值往不同大小的bytesXX的转换(显式或隐式) 不允许使用years 十六进制值后不允许加单位(比如0x1e wei) 十六进制值不允许用0X,只能使用0x 变量相关...已经不合法,需要显式指明x的存储类型,比如 ? image 再比如 ? image 也不合法,需要指明参数x的存储类型 ?...禁止无关合约类型变量之间的转换,通常情况下只能在合约有直接或间接继承关系时,才可以进行类型转换。...禁止不同大小的bytesX与uintY的转换,因为bytesX在右端补齐,而uintY在左 端,这可能会导致异常转换。现在必须先将大小调制为一致,再进行转换。

    2.1K70

    【C++重载操作符与转换】转换与继承

    一、继承转换的核心概念 1.1 向上转型与向下转型 在继承体系中,类型转换分为两种基本方向: 转换方向 安全性 转换方式 典型场景 向上转型 自动安全转换 隐式/static_cast 多态函数参数传递...形参列表为空,通过const限定保证转换不修改对象状态。 转换函数应避免修改被转换对象(通常声明为const成员)。 2.2 显式与隐式转换 隐式转换:当上下文需要目标类型时自动触发。...五、最佳实践与注意事项 ①类型转换运算符: 避免隐式转换导致的意外行为,优先使用explicit(C++11起支持)。 转换函数应保持无副作用,避免修改对象状态。...②继承设计: 优先使用组合而非继承,除非存在明确的"is-a"关系。 多重继承需谨慎,优先考虑接口继承(纯虚类)。 ③资源管理: 基类析构函数必须声明为virtual,防止内存泄漏。...类型转换运算符:实现对象与内置类型的无缝交互,需权衡隐式转换的便利性与安全性。 继承机制:通过单继承、多继承和虚继承,构建灵活的类层次结构,支持代码复用与多态。

    11310

    【C++】类型转换

    转换失败会导致编译错误 示例: int i = 10; float f = i; // 隐式将int转换为float 1.2 显式强制类型转换 需要程序员明确指定转换类型 使用强制类型转换运算符:...类型安全的语言通常具有以下特征: 严格的类型检查机制 禁止或限制隐式类型转换 提供明确的类型转换操作符 运行时类型识别(RTTI)支持 • C语言不是类型安全的语言,主要表现在: 允许广泛的隐式类型转换...:在继承层次结构中进行安全的向下转换 特点: 向下转换(基类到派生类) 横向转换(同一层次不同派生类之间) 运行时类型检查 示例: class A { public: virtual void f(...实现原理: 通过虚表(vtable)获取运行时类型信息(RTTI) 检查类型兼容性 调整指针位置(多重继承情况下) 返回转换结果或抛出异常 特殊要求: 基类必须包含至少一个虚函数 需要启用RTTI支持...与静态类型识别不同,RTTI允许程序在运行时(而不是编译时)动态获取对象的类型信息,这在多态场景下特别有用。例如,在处理基类指针指向派生类对象时,RTTI可以帮助确定实际的对象类型。

    24910

    C++ 类使用规范建议

    定义:通常,只有一个参数的构造函数可被用于转换(conversion,译者注:主要指隐式转换,下文可见),例如,定义了Foo::Foo(string name),当向需要传入一个Foo对象的函数传入一个字符串时...看上去很方便,但如果你并不希望如此通过转换生成一个新对象的话,麻烦也随之而来。为避免构造函数被调用造成隐式转换,可以将其声明为explicit。 优点:避免不合时宜的变换。 缺点:无。...Interface为后缀的纯接口类时才会使用多重继承。...缺点:真正需要用到多重实现继承的时候非常少,多重实现继承看上去是不错的解决方案,通常可以找到更加明确、清晰的、不同的解决方案。 结论:只有当所有父类除第一个外都是纯接口(纯抽象类)时才能使用多重继承。...; (3)为避免隐式转换,需将单参数构造函数声明为explicit; (4)为避免拷贝构造函数、赋值操作的滥用和编译器自动生成,可声明其为private且无需实现; (5)仅在作为数据集合时使用struct

    2.2K20

    《C++Primer》第十八章 用于大型程序的工具

    : Bear(name, ohExhibit, "Panda"), Endangered(Endagered::critical) { } // 隐式地使用Bear的默认构造函数初始化Bear...只有当派生类使用的是合成版本的拷贝、移动或赋值成员时,才会自动对其基类部分执行这些操作。在合成的拷贝控制成员中,每个基类分别使用自己对应成员隐式地完成构造、赋值或销毁等工作。...多重继承下的类作用域 在只有一个基类的情况下,派生类的作用域嵌套在直接基类和间接基类的作用域中。查找过程沿着继承体系自底向上进行,直到找到所需的名字。派生类的名字将隐藏基类的同名成员。...在多重继承的情况下,相同的查找过程在所有直接基类中同时进行,如果名字在多个基类中都被找到,则对该名字的使用将具有二义性。...对于一个派生类而言,从它的几个基类中分别继承名字相同的成员是完全合法的,只不过在使用这个名字时必须明确指出它的版本。

    1.8K20

    Google C++ 编程风格指南(三):类

    显式构造函数 对单个参数的构造函数使用 C++ 关键字 explicit. 定义: 通常, 如果构造函数只有一个参数, 可看成是一种隐式转换....看上去很方便, 但如果你并不希望如此通过转换生成一个新对象的话, 麻烦也随之而来. 为避免构造函数被调用造成隐式转换, 可以将其声明为 explicit....拷贝 / 移动构造函数在某些情况下会被编译器隐式调用. 例如, 通过传值的方式传递对象....移动操作允许隐式且高效地将源数据转移出右值对象. 这有时能让代码风格更加清晰. 缺点: 许多类型都不需要拷贝, 为它们提供拷贝操作会让人迷惑, 也显得荒谬而不合理....译者 (YuleFox) 笔记 不在构造函数中做太多逻辑相关的初始化; 编译器提供的默认构造函数不会对变量进行初始化, 如果定义了其他构造函数, 编译器不再提供, 需要编码者自行提供默认构造函数; 为避免隐式转换

    1.1K40

    Effective_Cpp中的55个建议

    2.对原始资源的访问可能经由显式转换或隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。...什么是新type的合法值? 你的新type需要配合某个继承图系吗? 你的新type需要什么样的转换? 什么样的操作符和函数对此新type而言是合理的? 什么样的标准函数应该驳回?...在实现域,复合意味着is-implemented-in-terms-of(根据某物实现出) 39:明智而审慎地使用private继承 40:明智而审慎地使用多重继承 1.非必要不要使用虚基类,平时请使用非虚继承...如果你必须使用虚基类,尽可能避免在其中饭放置数据。 2.多重继承比单一继承复杂。他可能导致新的歧义性,以及对虚继承的需要。 3.虚继承会增加大小、速度、初始化(及赋值)复杂度等成本。...4.多重继承的确有正当用途。其中一个情节涉及public继承某个接口类和私有继承某个协助实现的class的两相结合。

    90530

    C++转型操作符 VS 强制类型转换:为何前者更胜一筹?

    C++中的类型转换操作一、C++转型操作符的种类及用途1.1 static_cast主要用途:进行隐式类型转换,如将 int 转换为 float,或指针转换为 void*。...调用显式或隐式的转换函数,可增加代码可读性。在继承体系中进行类型转换:向上转换(派生类到基类)通常是安全的隐式转换,无需使用 static_cast。...向下转换(基类到派生类)需使用 static_cast,但不能通过虚拟继承转换,且不进行运行时检查,若目标类型并非对象实际类型会导致未定义行为。...限制:不能在存在“钻石继承”且未使用虚拟继承的情况下工作。只能通过公共继承进行转换,无法通过受保护或私有继承进行转换。...C 风格强制类型转换仅在编译时进行,不考虑转换合法性,可能导致运行时错误。

    38200

    Google C++编程风格指南(四)之类的相关规范

    定义:通常,只有一个参数的构造函数可被用于转换(conversion,译者注:主要指隐式转换,下文可见),例如,定义了Foo::Foo(string name),当向需要传入一个Foo对象的函数传入一个字符串时...看上去很方便,但如果你并不希望如此通过转换生成一个新对象的话,麻烦也随之而来。为避免构造函数被调用造成隐式转换,可以将其声明为explicit。 优点:避免不合时宜的变换。 缺点:无。...Interface为后缀的纯接口类时才会使用多重继承。...缺点:真正需要用到多重实现继承的时候非常少,多重实现继承看上去是不错的解决方案,通常可以找到更加明确、清晰的、不同的解决方案。 结论:只有当所有父类除第一个外都是纯接口(纯抽象类)时才能使用多重继承。...; 为避免隐式转换,需将单参数构造函数声明为explicit; 为避免拷贝构造函数、赋值操作的滥用和编译器自动生成,可目前声明其为private且无需实现; 仅在作为数据集合时使用struct; 优先以如下顺序来设计代码

    1.2K21

    【笔记】《Effective C++》条款26-55

    (empty base optimization)的原因不会占用额外的字节 40 明智而审慎地使用多重继承 多重继承可能会导致很多歧义, 例如要调用两个基类都有的同名函数时, 需要进行匹配性计算, 这个匹配计算与函数的访问性无关..., 我们提前进行的设计需要尽量满足表达式的输入和返回的类型 不管是显式接口还是隐式接口, 都在编译期完成检查, 因此我们都要好好检查, 可能被传入模板的类型到底能不能满足模板的隐式接口 42 了解typename...但是简化的时候也要注意有些时候抽离得越复杂, 副作用就越多, 所以要形成效率与安全性之间的取舍 45 运用成员函数模板接受所有兼容类型 模板之间并没有什么类似继承关系的固有关系, 无法自动在继承类之间进行隐式转换...在自身底层是T类型的指针时, 接受一个U类型的指针作为构造函数的参数, 然后通过原始指针本身的转换和继承形式将T类型转为了U类型, 从而实现了模板类的隐式类型转换 这类的转换的接口形如下图: 46...需要类型转换的时候请为模板定义非成员函数 模板函数进行实参推导的过程中不会自动考虑模板函数的隐式类型转换, 因为从一开始编译器就看不见这个目标转换函数 如果想要写一个可以隐式处理模板类的函数(例如运算符

    1.3K30
    领券