在面向对象编程中,转换构造函数和运算符有助于将对象从一种类型转换为另一种类型。但是,可能会出现存在多个可行转换路径的情况,从而提出哪一个优先的问题。
在给定的代码片段中,在将 A 对象分配给 B 变量(B b = A();),尽管同时存在转换运算符和转换构造函数。以下部分深入探讨了这种行为背后的基本原理及其哲学含义。
C 标准在第 13.3.1.4 节中建立了解决不明确转换调用的优先级,其中声明使用重载解析来选择“最佳”用户定义的转换。在这种情况下,候选函数既包括 B 的转换构造函数,也包括 A 的转换运算符。
当源类型和目标类型是不同的类(S 和 T)时,编译器会初始化类型 T 的对象(通过复制初始化)通过应用一系列转换步骤。该标准考虑了 S 及其基类的转换函数。产生类型匹配或从 T 派生而无需附加 cv 限定符的转换函数成为候选函数。此步骤导致选择运算符 B() 和 B(const A&) 作为我们案例中的候选者。
随后,C 标准应用重载解析来确定参数的最佳匹配。参数列表由该实例中的初始值设定项表达式组成。在我们的代码中,参数是一个 A 对象,它是一个左值。
决定优先级的关键因素封装在第 13.3.3.2/3 节中:“如果两个候选函数都是引用绑定并且引用兼容的类型,引用上具有最少 cv 限定的类型是首选。”
在我们的代码中,运算符 B() 由于是而采用类型 A 的左值成员函数,而 B(const A&) 采用 const 引用。由于运算符 B() 的 const 限定较少,因此编译器将其选为最佳候选,从而调用转换运算符。
来自哲学从角度来看,A 或 B 是否对如何进行转换有更多了解的选择是值得商榷的。
一方面,人们可能会认为 B(目标类型)是知识渊博的一方,因为它负责定义如何从 A 对象构造自身。 B 中的转换构造函数可以封装特定的转换规则或验证。
另一方面,人们可以主张 A(源类型)对其自身的表示以及如何将其解释为 B 拥有更深入的了解目的。 A 中的转换运算符允许对象控制如何将其转换为 B。
最终,C 标准选择了转换运算符优先的方法,优先考虑源对象的表示。这种选择符合这样的观念:对象本身最了解其自身的内部状态以及如何将其转换为其他类型。但是,必须注意的是,此优先级规则受重载解析规则的约束,因此最终决定可能会受到 const 限定等其他因素的影响,如我们的示例代码所示。
以上是将对象从一种类型转换为另一种类型时,为什么转换运算符优先于转换构造函数?的详细内容。更多信息请关注PHP中文网其他相关文章!