你有反差。
返回类型隐式转换为基本类型(逆变)。但是参数隐式转换为派生类型(协方差),并且指向成员的类类型可以作为参数。要看到这一点,让我们应用Liskov可替代性原则:
Base*
的合同是:“我会给你一个基地”(当你对我使用*
运营商时)。 Derived*
合同是“我会给你一个派生的,这也是一个基地”。
显然,Derived*
可以用来代替Base*
。因此存在从Derived*
到Base*
的隐式转换。
但是考虑指向成员的指针。
的int Base::*
的合同是:“给我一个基地,我会还给你一个int”(A派生是基础,所以这些都是OK太) 的int Derived::*
的合同是:“给我一个推导我会给你回一个int”(但不是任何旧Base
会做,它必须是一个Derived
)
假设你有一个Base
这不是一个Derived
。当解引用int Base::*
时它会很好地工作,但不能与int Derived*
一起使用)。
但是,如果您有
Derived
,则可以使用它取消引用
int Base::*
和
int Derived::*
。因此,有从
int Base::*
到
int Derived::*
哎呀隐式转换,我没有你所说的话,并分析了该成员所属的类型。
虽然LSP仍然有效。我同意转换应该是合法的,至少根据类型安全。合同是“给我一个Foo
,我会给你一个Derived
”,这显然你可以用它来从Foo
到Base
,通过组成一个隐式转换。所以它很安全。 DeadMG可能在正确的轨道上指出了与基本子对象的关系位置的潜在复杂性,特别是在虚拟继承中。但是指针成员在解除引用运算符的LHS中处理这些问题,所以他们也可以得出结果。
最终答案可能只是标准并不要求转换是合法的。
“通常允许从基础*转换为派生*” 我认为你有这个落后。 – 2010-12-09 22:33:03
好的。固定。 – Chris 2010-12-09 22:38:59
见http://stackoverflow.com/questions/4295117/pointer-to-member-conversion – icecrime 2010-12-09 22:57:59