gpt4 book ai didi

c++ - 指向数据成员与非成员的指针的隐式转换

转载 作者:可可西里 更新时间:2023-11-01 18:38:49 25 4
gpt4 key购买 nike

我看到的大多数关于成员指针的讨论都集中在成员所属类型允许的转换上。我的问题是关于成员(member)类型的转换。

struct Base{};
struct Derived : public Base{};
struct Foo{ Derived m_Derived; };

鉴于这些声明,以下代码会产生错误 (MSVC 2008):

// error C2440: 'initializing' : cannot convert from 'Derived Foo::* ' to 'Base Foo::* '
Base Foo::*p = &Foo::m_Derived;

通常允许从 Derived* 到 Base* 的转换 - 为什么这里有区别?

最佳答案

你的方差向后。

返回类型隐式转换为基本类型(逆变)。但是参数隐式转换为派生类型(协变),指向成员的指针中的类类型充当参数。为了解这一点,让我们应用 Liskov 可替代性原则:

Base*的约定是:“我给你一个Base”(当你对我使用*操作符时)。Derived*的约定是“我给你一个Derived,也是一个Base”。

显然 Derived* 可以用来代替 Base*。因此,存在从 Derived*Base* 的隐式转换。

但是考虑指向成员的指针的契约。

int Base::* 的契约是:“给我一个 Base,我会还给你一个 int”(派生是一个 Base,所以那些也可以)int Derived::* 的契约是:“给我一个 Derived,我会还给你一个 int”(但不是任何旧的 Base 都可以,它必须是派生)

假设您有一个 Base 而不是 Derived。它在取消引用 int Base::* 时会很好地工作,但不能与 int Derived* 一起使用。

但是,如果您有一个 Derived,您可以使用它来取消引用 int Base::*int Derived::*。因此,存在从 int Base::*int Derived::* 的隐式转换

哎呀,我按照你说的做了,分析了成员(member)属于什么类型。

LSP 仍然有效。我同意转换应该是合法的,至少根据类型安全。契约(Contract)是“给我一个 Foo,我会给你一个 Derived”,显然你可以用它来从 Foo >Base 通过将其与隐式转换组合在一起。所以很安全。 DeadMG 可能在正确的轨道上指出了基础子对象的关系位置的潜在复杂性,尤其是在虚拟继承中。但是指向成员的指针在取消引用运算符的 LHS 上处理这些问题,因此它们也可以处理结果。

最终的答案可能只是标准不要求转换是合法的。

关于c++ - 指向数据成员与非成员的指针的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4403786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com