【问题标题】:Member Pointer to Base Class指向基类的成员指针
【发布时间】:2010-01-31 17:28:43
【问题描述】:

所有。我无法理解为什么下面的代码需要强制转换才能工作。谁能解释一下?

class Base {
};

class Derived : public Base {
};

class Class {
public:
    Derived member;
};

...

Derived obj;
Base *ptrObj = &obj; // ok, no cast needed

Derived Class::* ptr = &Class::member; // ok
Base    Class::* ptr = &Class::member; // wrong, need cast, why?

【问题讨论】:

  • 我以前从未见过这种语法;有人将我链接到它的含义,不可能在谷歌上搜索这些东西
  • 这是一个指向成员的指针。 :-)

标签: c++ inheritance casting pointers member


【解决方案1】:

因为如果Base 被允许(协变),那么您可以这样做,这是一个禁忌:

Base Class::* ptr = &Class::member;
Class obj;
obj.*ptr = Base();   // <-- assigned a Base into a Derived field?!

同时,指向成员的指针也不能是逆变的,否则你可以这样做,这也是一个禁忌:

struct Class2 {
    Base member;
};

Derived Class2::* ptr2 = &Class2::member;
Class2 obj2;
obj2.member = Base();
Derived& d = obj2.*ptr2;  // <-- assigned a Base into a Derived

因此,指向成员的指针既不是协变的也不是逆变的,而是不变的:类型必须完全匹配。

【讨论】:

  • 这不是很有说服力。您可以使用普通指针将基分配给派生(否则将不允许将派生类指针转换为基类指针),那么为什么不使用成员指针呢?
【解决方案2】:

好的,克里斯,我明白了你的意思,但你的第一个例子适用于普通指针。为什么它也不适用于成员指针?请参阅下面的代码。

Derived obj;
Base *ptr = &obj;

*ptr = Base(); // it's weird, but ok

第二个例子即使对于普通指针也不起作用,因为没有强制转换就不允许向下转换。所以我认为这不应该是一个解释。

【讨论】:

  • 使用“添加评论”功能将 cmets 添加到答案中,或者编辑您的问题,而不是发布非答案。
  • 这和他的第一个例子不一样。您不能使用普通指针说Derived* obj = Base(),因为Base 不是Derived。如果Derived 有不在Base 中的someInt 会发生什么?那么当objBase 时,当您执行obj-&gt;someInt 时会发生什么?
猜你喜欢
  • 2018-03-24
  • 2021-12-03
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 2011-04-21
相关资源
最近更新 更多